TK Soh's implementation of clonable windows http://sourceforge.net/tracker/index.php?func=detail&aid=1180552&group_id=11005&atid=311005 [ 1180552 ] MV's cloned windows MV's cloned windows: This is a port of Max Vohlken's window cloning patch, which is part of his original patch for NEdit 5.0.2. Use the menu Windows->Clone Tab to create a new window, which is a clone of the invoking tab. Split panes will also be cloned. The tabs, window and icon titles will reflect the clone status with an additional "<#>" appended to the filenames, with # being the index of the clone. As of v1.0, you can't move or detach a clone, but we may expect this to change in the future version. Have fun! [modified to adjust for changing base source code] diff -ur nedit_official nedit_mod diff -ur nedit_official/source/file.c nedit_mod/source/file.c --- nedit_official/source/file.c 2008-03-15 15:43:08.000000000 +0100 +++ nedit_mod/source/file.c 2008-03-18 00:23:59.000000000 +0100 @@ -123,14 +123,14 @@ /* create new window/document */ if (inWindow) - window = CreateDocument(inWindow, name); + window = CreateDocument(inWindow, name, NULL); else - window = CreateWindow(name, geometry, iconic); + window = CreateWindow(name, geometry, iconic, NULL); - path = window->path; - strcpy(window->filename, name); + path = window->editorInfo->path; + strcpy(window->editorInfo->filename, name); strcpy(path, (defaultPath && *defaultPath) ? defaultPath : GetCurrentDir()); - pathlen = strlen(window->path); + pathlen = strlen(path); #ifndef VMS /* do we have a "/" at the end? if not, add one */ if (0 < pathlen && path[pathlen - 1] != '/' && pathlen < MAXPATHLEN - 1) { @@ -150,7 +150,7 @@ /* TODO: what about other platforms? */ #endif /* VMS */ SetWindowModified(window, FALSE); - CLEAR_ALL_LOCKS(window->lockReasons); + CLEAR_ALL_LOCKS(window->editorInfo->lockReasons); UpdateWindowReadOnly(window); UpdateStatsLine(window); UpdateWindowTitle(window); @@ -214,22 +214,22 @@ in use (not Untitled or Untitled and modified), or is currently busy running a macro; create the window */ if (inWindow == NULL) { - window = CreateWindow(name, geometry, iconic); + window = CreateWindow(name, geometry, iconic, NULL); } - else if (inWindow->filenameSet || inWindow->fileChanged || + else if (inWindow->editorInfo->filenameSet || inWindow->editorInfo->fileChanged || inWindow->macroCmdData != NULL) { if (tabbed) { - window = CreateDocument(inWindow, name); + window = CreateDocument(inWindow, name, NULL); } else { - window = CreateWindow(name, geometry, iconic); + window = CreateWindow(name, geometry, iconic, NULL); } } else { /* open file in untitled document */ window = inWindow; - strcpy(window->path, path); - strcpy(window->filename, name); + strcpy(window->editorInfo->path, path); + strcpy(window->editorInfo->filename, name); if (!iconic && !bgOpen) { RaiseDocumentWindow(window); } @@ -285,11 +285,11 @@ Widget text; /* Can't revert untitled windows */ - if (!window->filenameSet) + if (!window->editorInfo->filenameSet) { DialogF(DF_WARN, window->shell, 1, "Error", "Window '%s' was never saved, can't re-read", "OK", - window->filename); + window->editorInfo->filename); return; } @@ -301,22 +301,22 @@ } /* re-read the file, update the window title if new file is different */ - strcpy(name, window->filename); - strcpy(path, window->path); + strcpy(name, window->editorInfo->filename); + strcpy(path, window->editorInfo->path); RemoveBackupFile(window); ClearUndoList(window); - openFlags |= IS_USER_LOCKED(window->lockReasons) ? PREF_READ_ONLY : 0; + openFlags |= IS_USER_LOCKED(window->editorInfo->lockReasons) ? PREF_READ_ONLY : 0; if (!doOpen(window, name, path, openFlags)) { /* This is a bit sketchy. The only error in doOpen that irreperably damages the window is "too much binary data". It should be pretty rare to be reverting something that was fine only to find that now it has too much binary data. */ - if (!window->fileMissing) + if (!window->editorInfo->fileMissing) safeClose(window); else { /* Treat it like an externally modified file */ - window->lastModTime=0; - window->fileMissing=FALSE; + window->editorInfo->lastModTime=0; + window->editorInfo->fileMissing=FALSE; } return; } @@ -363,13 +363,13 @@ int resp; /* initialize lock reasons */ - CLEAR_ALL_LOCKS(window->lockReasons); + CLEAR_ALL_LOCKS(window->editorInfo->lockReasons); /* Update the window data structure */ - strcpy(window->filename, name); - strcpy(window->path, path); - window->filenameSet = TRUE; - window->fileMissing = TRUE; + strcpy(window->editorInfo->filename, name); + strcpy(window->editorInfo->path, path); + window->editorInfo->filenameSet = TRUE; + window->editorInfo->fileMissing = TRUE; /* Get the full name of the file */ strcpy(fullname, path); @@ -385,7 +385,7 @@ { if ((fp = fopen(fullname, "r")) != NULL) { if(access(fullname, W_OK) != 0) - SET_PERM_LOCKED(window->lockReasons, TRUE); + SET_PERM_LOCKED(window->editorInfo->lockReasons, TRUE); #else fp = fopen(fullname, "rb+"); if (fp == NULL) { @@ -393,7 +393,7 @@ fp = fopen(fullname, "rb"); if (fp != NULL) { /* File is read only */ - SET_PERM_LOCKED(window->lockReasons, TRUE); + SET_PERM_LOCKED(window->editorInfo->lockReasons, TRUE); #endif } else if (flags & CREATE && errno == ENOENT) { /* Give option to create (or to exit if this is the only window) */ @@ -439,7 +439,7 @@ SetWindowModified(window, FALSE); if ((flags & PREF_READ_ONLY) != 0) { - SET_USER_LOCKED(window->lockReasons, TRUE); + SET_USER_LOCKED(window->editorInfo->lockReasons, TRUE); } UpdateWindowReadOnly(window); return TRUE; @@ -457,29 +457,29 @@ last modification to the file */ if (fstat(fileno(fp), &statbuf) != 0) { fclose(fp); - window->filenameSet = FALSE; /* Temp. prevent check for changes. */ + window->editorInfo->filenameSet = FALSE; /* Temp. prevent check for changes. */ DialogF(DF_ERR, window->shell, 1, "Error opening File", "Error opening %s", "OK", name); - window->filenameSet = TRUE; + window->editorInfo->filenameSet = TRUE; return FALSE; } if (S_ISDIR(statbuf.st_mode)) { fclose(fp); - window->filenameSet = FALSE; /* Temp. prevent check for changes. */ + window->editorInfo->filenameSet = FALSE; /* Temp. prevent check for changes. */ DialogF(DF_ERR, window->shell, 1, "Error opening File", "Can't open directory %s", "OK", name); - window->filenameSet = TRUE; + window->editorInfo->filenameSet = TRUE; return FALSE; } #ifdef S_ISBLK if (S_ISBLK(statbuf.st_mode)) { fclose(fp); - window->filenameSet = FALSE; /* Temp. prevent check for changes. */ + window->editorInfo->filenameSet = FALSE; /* Temp. prevent check for changes. */ DialogF(DF_ERR, window->shell, 1, "Error opening File", "Can't open block device %s", "OK", name); - window->filenameSet = TRUE; + window->editorInfo->filenameSet = TRUE; return FALSE; } #endif @@ -489,10 +489,10 @@ fileString = (char *)malloc(fileLen+1); /* +1 = space for null */ if (fileString == NULL) { fclose(fp); - window->filenameSet = FALSE; /* Temp. prevent check for changes. */ + window->editorInfo->filenameSet = FALSE; /* Temp. prevent check for changes. */ DialogF(DF_ERR, window->shell, 1, "Error while opening File", "File is too large to edit", "OK"); - window->filenameSet = TRUE; + window->editorInfo->filenameSet = TRUE; return FALSE; } @@ -500,10 +500,10 @@ readLen = fread(fileString, sizeof(char), fileLen, fp); if (ferror(fp)) { fclose(fp); - window->filenameSet = FALSE; /* Temp. prevent check for changes. */ + window->editorInfo->filenameSet = FALSE; /* Temp. prevent check for changes. */ DialogF(DF_ERR, window->shell, 1, "Error while opening File", "Error reading %s:\n%s", "OK", name, errorString()); - window->filenameSet = TRUE; + window->editorInfo->filenameSet = TRUE; free(fileString); return FALSE; } @@ -520,35 +520,35 @@ /* Any errors that happen after this point leave the window in a "broken" state, and thus RevertToSaved will abandon the window if window->fileMissing is FALSE and doOpen fails. */ - window->fileMode = statbuf.st_mode; - window->fileUid = statbuf.st_uid; - window->fileGid = statbuf.st_gid; - window->lastModTime = statbuf.st_mtime; - window->device = statbuf.st_dev; - window->inode = statbuf.st_ino; - window->fileMissing = FALSE; + window->editorInfo->fileMode = statbuf.st_mode; + window->editorInfo->fileUid = statbuf.st_uid; + window->editorInfo->fileGid = statbuf.st_gid; + window->editorInfo->lastModTime = statbuf.st_mtime; + window->editorInfo->device = statbuf.st_dev; + window->editorInfo->inode = statbuf.st_ino; + window->editorInfo->fileMissing = FALSE; /* Detect and convert DOS and Macintosh format files */ if (GetPrefForceOSConversion()) { - window->fileFormat = FormatOfFile(fileString); - if (window->fileFormat == DOS_FILE_FORMAT) { + window->editorInfo->fileFormat = FormatOfFile(fileString); + if (window->editorInfo->fileFormat == DOS_FILE_FORMAT) { ConvertFromDosFileString(fileString, &readLen, NULL); - } else if (window->fileFormat == MAC_FILE_FORMAT) { + } else if (window->editorInfo->fileFormat == MAC_FILE_FORMAT) { ConvertFromMacFileString(fileString, readLen); } } /* Display the file contents in the text widget */ - window->ignoreModify = True; - BufSetAll(window->buffer, fileString); - window->ignoreModify = False; + window->editorInfo->ignoreModify = True; + BufSetAll(window->editorInfo->buffer, fileString); + window->editorInfo->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)) { + if (window->editorInfo->buffer->length != readLen) { + if (!BufSubstituteNullChars(fileString, readLen, window->editorInfo->buffer)) { resp = DialogF(DF_ERR, window->shell, 2, "Error while opening File", "Too much binary data in file. You may view\n" "it, but not modify or re-save its contents.", "View", @@ -557,17 +557,17 @@ return FALSE; } - SET_TMBD_LOCKED(window->lockReasons, TRUE); + SET_TMBD_LOCKED(window->editorInfo->lockReasons, TRUE); for (c = fileString; c < &fileString[readLen]; c++) { if (*c == '\0') { *c = (char) 0xfe; } } - window->buffer->nullSubsChar = (char) 0xfe; + window->editorInfo->buffer->nullSubsChar = (char) 0xfe; } - window->ignoreModify = True; - BufSetAll(window->buffer, fileString); - window->ignoreModify = False; + window->editorInfo->ignoreModify = True; + BufSetAll(window->editorInfo->buffer, fileString); + window->editorInfo->ignoreModify = False; } /* Release the memory that holds fileString */ @@ -575,14 +575,14 @@ /* Set window title and file changed flag */ if ((flags & PREF_READ_ONLY) != 0) { - SET_USER_LOCKED(window->lockReasons, TRUE); + SET_USER_LOCKED(window->editorInfo->lockReasons, TRUE); } - if (IS_PERM_LOCKED(window->lockReasons)) { - window->fileChanged = FALSE; + if (IS_PERM_LOCKED(window->editorInfo->lockReasons)) { + window->editorInfo->fileChanged = FALSE; UpdateWindowTitle(window); } else { SetWindowModified(window, FALSE); - if (IS_ANY_LOCKED(window->lockReasons)) { + if (IS_ANY_LOCKED(window->editorInfo->lockReasons)) { UpdateWindowTitle(window); } } @@ -661,7 +661,7 @@ } /* If the file contained ascii nulls, re-map them */ - if (!BufSubstituteNullChars(fileString, readLen, window->buffer)) + if (!BufSubstituteNullChars(fileString, readLen, window->editorInfo->buffer)) { DialogF(DF_ERR, window->shell, 1, "Error opening File", "Too much binary data in file", "OK"); @@ -678,10 +678,10 @@ /* insert the contents of the file in the selection or at the insert position in the window if no selection exists */ - if (window->buffer->primary.selected) - BufReplaceSelected(window->buffer, fileString); + if (window->editorInfo->buffer->primary.selected) + BufReplaceSelected(window->editorInfo->buffer, fileString); else - BufInsert(window->buffer, TextGetCursorPos(window->lastFocus), + BufInsert(window->editorInfo->buffer, TextGetCursorPos(window->lastFocus), fileString); /* release the memory that holds fileString */ @@ -696,7 +696,7 @@ int CloseAllFilesAndWindows(void) { while (WindowList->next != NULL || - WindowList->filenameSet || WindowList->fileChanged) { + WindowList->editorInfo->filenameSet || WindowList->editorInfo->fileChanged) { /* * When we're exiting through a macro, the document running the * macro does not disappear from the list, so we could get stuck @@ -726,17 +726,20 @@ int response, stat; /* Make sure that the window is not in iconified state */ - if (window->fileChanged) + if (window->editorInfo->fileChanged) RaiseDocumentWindow(window); /* If the window is a normal & unmodified file or an empty new file, or if the user wants to ignore external modifications then just close it. Otherwise ask for confirmation first. */ - if (!window->fileChanged && + if (window->editorInfo->master->nextSlave) { + CloseWindow(window); + } + else if (!window->editorInfo->fileChanged && /* Normal File */ - ((!window->fileMissing && window->lastModTime > 0) || + ((!window->editorInfo->fileMissing && window->editorInfo->lastModTime > 0) || /* New File*/ - (window->fileMissing && window->lastModTime == 0) || + (window->editorInfo->fileMissing && window->editorInfo->lastModTime == 0) || /* File deleted/modified externally, ignored by user. */ !GetPrefWarnFileMods())) { @@ -747,7 +750,7 @@ if (preResponse == PROMPT_SBC_DIALOG_RESPONSE) { response = DialogF(DF_WARN, window->shell, 3, "Save File", - "Save %s before closing?", "Yes", "No", "Cancel", window->filename); + "Save %s before closing?", "Yes", "No", "Cancel", window->editorInfo->filename); } else { response = preResponse; @@ -786,12 +789,12 @@ /* Return success if the file is normal & unchanged or is a read-only file. */ - if ( (!window->fileChanged && !window->fileMissing && - window->lastModTime > 0) || - IS_ANY_LOCKED_IGNORING_PERM(window->lockReasons)) + if ( (!window->editorInfo->fileChanged && !window->editorInfo->fileMissing && + window->editorInfo->lastModTime > 0) || + IS_ANY_LOCKED_IGNORING_PERM(window->editorInfo->lockReasons)) return TRUE; /* Prompt for a filename if this is an Untitled window */ - if (!window->filenameSet) + if (!window->editorInfo->filenameSet) return SaveWindowAs(window, NULL, False); /* Check for external modifications and warn the user */ @@ -805,12 +808,12 @@ "To preserve the modified file, cancel this operation and\n" "use Save As... to save this file under a different name,\n" "or Revert to Saved to revert to the modified version.", - "Continue", "Cancel", window->filename); + "Continue", "Cancel", window->editorInfo->filename); if (stat == 2) { /* Cancel and mark file as externally modified */ - window->lastModTime = 0; - window->fileMissing = FALSE; + window->editorInfo->lastModTime = 0; + window->editorInfo->fileMissing = FALSE; return FALSE; } } @@ -840,7 +843,7 @@ &fileFormat, &addWrap); if (response != GFN_OK) return FALSE; - window->fileFormat = fileFormat; + window->editorInfo->fileFormat = fileFormat; } else { strcpy(fullname, newName); @@ -860,8 +863,8 @@ } /* If the requested file is this file, just save it and return */ - if (!strcmp(window->filename, filename) && - !strcmp(window->path, pathname)) { + if (!strcmp(window->editorInfo->filename, filename) && + !strcmp(window->editorInfo->path, pathname)) { if (writeBckVersion(window)) return FALSE; return doSave(window); @@ -896,12 +899,12 @@ /* Change the name of the file and save it under the new name */ RemoveBackupFile(window); - strcpy(window->filename, filename); - strcpy(window->path, pathname); - window->fileMode = 0; - window->fileUid = 0; - window->fileGid = 0; - CLEAR_ALL_LOCKS(window->lockReasons); + strcpy(window->editorInfo->filename, filename); + strcpy(window->editorInfo->path, pathname); + window->editorInfo->fileMode = 0; + window->editorInfo->fileUid = 0; + window->editorInfo->fileGid = 0; + CLEAR_ALL_LOCKS(window->editorInfo->lockReasons); retVal = doSave(window); UpdateWindowReadOnly(window); RefreshTabState(window); @@ -912,10 +915,10 @@ /* If name has changed, language mode may have changed as well, unless it's an Untitled window for which the user already set a language mode; it's probably the right one. */ - if (PLAIN_LANGUAGE_MODE == window->languageMode || window->filenameSet) { + if (PLAIN_LANGUAGE_MODE == window->languageMode || window->editorInfo->filenameSet) { DetermineLanguageMode(window, False); } - window->filenameSet = True; + window->editorInfo->filenameSet = True; /* Update the stats line and window title with the new filename */ UpdateWindowTitle(window); @@ -934,8 +937,8 @@ int fileLen, result; /* Get the full name of the file */ - strcpy(fullname, window->path); - strcat(fullname, window->filename); + strcpy(fullname, window->editorInfo->path); + strcat(fullname, window->editorInfo->filename); /* Check for root and warn him if he wants to write to a file with none of the write bits set. */ @@ -946,7 +949,7 @@ result = DialogF(DF_WARN, window->shell, 2, "Writing Read-only File", "File '%s' is marked as read-only.\n" "Do you want to save anyway?", - "Save", "Cancel", window->filename); + "Save", "Cancel", window->editorInfo->filename); if (1 != result) { return True; @@ -965,11 +968,11 @@ changes. If the file is created for the first time, it has zero size on disk, and the check would falsely conclude that the file has changed on disk, and would pop up a warning dialog */ - if (BufGetCharacter(window->buffer, window->buffer->length - 1) != '\n' - && window->buffer->length != 0 + if (BufGetCharacter(window->editorInfo->buffer, window->editorInfo->buffer->length - 1) != '\n' + && window->editorInfo->buffer->length != 0 && GetPrefAppendLF()) { - BufInsert(window->buffer, window->buffer->length, "\n"); + BufInsert(window->editorInfo->buffer, window->editorInfo->buffer->length, "\n"); } /* open the file */ @@ -983,7 +986,7 @@ result = DialogF(DF_WARN, window->shell, 2, "Error saving File", "Unable to save %s:\n%s\n\nSave as a new file?", "Save As...", "Cancel", - window->filename, errorString()); + window->editorInfo->filename, errorString()); if (result == 1) { @@ -998,14 +1001,14 @@ #endif /* get the text buffer contents and its length */ - fileString = BufGetAll(window->buffer); - fileLen = window->buffer->length; + fileString = BufGetAll(window->editorInfo->buffer); + fileLen = window->editorInfo->buffer->length; /* If null characters are substituted for, put them back */ - BufUnsubstituteNullChars(fileString, window->buffer); + BufUnsubstituteNullChars(fileString, window->editorInfo->buffer); /* If the file is to be saved in DOS or Macintosh format, reconvert */ - if (window->fileFormat == DOS_FILE_FORMAT) + if (window->editorInfo->fileFormat == DOS_FILE_FORMAT) { if (!ConvertToDosFileString(&fileString, &fileLen)) { @@ -1013,7 +1016,7 @@ "Out of memory! Try\nsaving in Unix format", "OK"); return FALSE; } - } else if (window->fileFormat == MAC_FILE_FORMAT) + } else if (window->editorInfo->fileFormat == MAC_FILE_FORMAT) { ConvertToMacFileString(fileString, fileLen); } @@ -1027,7 +1030,7 @@ if (ferror(fp)) { DialogF(DF_ERR, window->shell, 1, "Error saving File", - "%s not saved:\n%s", "OK", window->filename, errorString()); + "%s not saved:\n%s", "OK", window->editorInfo->filename, errorString()); fclose(fp); remove(fullname); XtFree(fileString); @@ -1048,7 +1051,7 @@ #ifdef VMS /* reflect the fact that NEdit is now editing a new version of the file */ - ParseFilename(fullname, window->filename, window->path); + ParseFilename(fullname, window->editorInfo->filename, window->editorInfo->path); #endif /*VMS*/ /* success, file was written */ @@ -1056,17 +1059,17 @@ /* update the modification time */ if (stat(fullname, &statbuf) == 0) { - window->lastModTime = statbuf.st_mtime; - window->fileMissing = FALSE; - window->device = statbuf.st_dev; - window->inode = statbuf.st_ino; + window->editorInfo->lastModTime = statbuf.st_mtime; + window->editorInfo->fileMissing = FALSE; + window->editorInfo->device = statbuf.st_dev; + window->editorInfo->inode = statbuf.st_ino; } else { /* This needs to produce an error message -- the file can't be accessed! */ - window->lastModTime = 0; - window->fileMissing = TRUE; - window->device = 0; - window->inode = 0; + window->editorInfo->lastModTime = 0; + window->editorInfo->fileMissing = TRUE; + window->editorInfo->device = 0; + window->editorInfo->inode = 0; } return TRUE; @@ -1103,9 +1106,9 @@ { DialogF(DF_WARN, window->shell, 1, "Error writing Backup", "Unable to save backup for %s:\n%s\n" - "Automatic backup is now off", "OK", window->filename, + "Automatic backup is now off", "OK", window->editorInfo->filename, errorString()); - window->autoSave = FALSE; + window->editorInfo->autoSave = FALSE; SetToggleButtonState(window, window->autoSaveItem, FALSE, FALSE); return FALSE; } @@ -1116,11 +1119,11 @@ #endif /* get the text buffer contents and its length */ - fileString = BufGetAll(window->buffer); - fileLen = window->buffer->length; + fileString = BufGetAll(window->editorInfo->buffer); + fileLen = window->editorInfo->buffer->length; /* If null characters are substituted for, put them back */ - BufUnsubstituteNullChars(fileString, window->buffer); + BufUnsubstituteNullChars(fileString, window->editorInfo->buffer); /* add a terminating newline if the file doesn't already have one */ if (fileLen != 0 && fileString[fileLen-1] != '\n') @@ -1136,12 +1139,12 @@ { DialogF(DF_ERR, window->shell, 1, "Error saving Backup", "Error while saving backup for %s:\n%s\n" - "Automatic backup is now off", "OK", window->filename, + "Automatic backup is now off", "OK", window->editorInfo->filename, errorString()); fclose(fp); remove(name); XtFree(fileString); - window->autoSave = FALSE; + window->editorInfo->autoSave = FALSE; return FALSE; } @@ -1165,7 +1168,7 @@ char name[MAXPATHLEN]; /* Don't delete backup files when backups aren't activated. */ - if (window->autoSave == FALSE) + if (window->editorInfo->autoSave == FALSE) return; backupFileName(window, name, sizeof(name)); @@ -1180,18 +1183,18 @@ { char bckname[MAXPATHLEN]; #ifdef VMS - if (window->filenameSet) - sprintf(name, "%s_%s", window->path, window->filename); + if (window->editorInfo->filenameSet) + sprintf(name, "%s_%s", window->editorInfo->path, window->editorInfo->filename); else - sprintf(name, "%s_%s", "SYS$LOGIN:", window->filename); + sprintf(name, "%s_%s", "SYS$LOGIN:", window->editorInfo->filename); #else - if (window->filenameSet) + if (window->editorInfo->filenameSet) { - sprintf(name, "%s~%s", window->path, window->filename); + sprintf(name, "%s~%s", window->editorInfo->path, window->editorInfo->filename); } else { strcpy(bckname, "~"); - strncat(bckname, window->filename, MAXPATHLEN - 1); + strncat(bckname, window->editorInfo->filename, MAXPATHLEN - 1); PrependHome(bckname, name, len); } #endif /*VMS*/ @@ -1212,17 +1215,17 @@ #define IO_BUFFER_SIZE ((size_t)(1024*1024)) /* Do only if version backups are turned on */ - if (!window->saveOldVersion) { + if (!window->editorInfo->saveOldVersion) { return False; } /* Get the full name of the file */ - strcpy(fullname, window->path); - strcat(fullname, window->filename); + strcpy(fullname, window->editorInfo->path); + strcat(fullname, window->editorInfo->filename); /* Generate name for old version */ if ((strlen(fullname) + 5) > (size_t) MAXPATHLEN) { - return bckError(window, "file name too long", window->filename); + return bckError(window, "file name too long", window->editorInfo->filename); } sprintf(bckname, "%s.bck", fullname); @@ -1278,7 +1281,7 @@ close(out_fd); remove(bckname); free(io_buffer); - return bckError(window, "read() error", window->filename); + return bckError(window, "read() error", window->editorInfo->filename); } if (0 == bytes_read) { @@ -1321,7 +1324,7 @@ if (resp == 1) return TRUE; if (resp == 2) { - window->saveOldVersion = FALSE; + window->editorInfo->saveOldVersion = FALSE; #ifndef VMS SetToggleButtonState(window, window->saveLastItem, FALSE, FALSE); #endif @@ -1331,7 +1334,7 @@ void PrintWindow(WindowInfo *window, int selectedOnly) { - textBuffer *buf = window->buffer; + textBuffer *buf = window->editorInfo->buffer; selection *sel = &buf->primary; char *fileString = NULL; int fileLen; @@ -1360,7 +1363,7 @@ fileString[fileLen++] = '\n'; /* null terminator no longer needed */ /* Print the string */ - PrintString(fileString, fileLen, window->shell, window->filename); + PrintString(fileString, fileLen, window->shell, window->editorInfo->filename); /* Free the text buffer copy returned from XmTextGetString */ XtFree(fileString); @@ -1447,12 +1450,12 @@ char *savedDefaultDir; int retVal; - /* Temporarily set default directory to window->path, prompt for file, + /* Temporarily set default directory to window->editorInfo->path, prompt for file, then, if the call was unsuccessful, restore the original default directory */ savedDefaultDir = GetFileDialogDefaultDirectory(); - if (*window->path != '\0') - SetFileDialogDefaultDirectory(window->path); + if (*window->editorInfo->path != '\0') + SetFileDialogDefaultDirectory(window->editorInfo->path); retVal = GetExistingFilename(window->shell, prompt, fullname); if (retVal != GFN_OK) SetFileDialogDefaultDirectory(savedDefaultDir); @@ -1477,14 +1480,14 @@ Widget formatForm, formatBtns, unixFormat, dosFormat, macFormat; char *savedDefaultDir; - *fileFormat = window->fileFormat; + *fileFormat = window->editorInfo->fileFormat; - /* Temporarily set default directory to window->path, prompt for file, + /* Temporarily set default directory to window->editorInfo->path, prompt for file, then, if the call was unsuccessful, restore the original default directory */ savedDefaultDir = GetFileDialogDefaultDirectory(); - if (*window->path != '\0') - SetFileDialogDefaultDirectory(window->path); + if (*window->editorInfo->path != '\0') + SetFileDialogDefaultDirectory(window->editorInfo->path); /* Present a file selection dialog with an added field for requesting long line wrapping to become permanent via inserted newlines */ @@ -1548,7 +1551,7 @@ XmStringFree(s1); XtAddCallback(macFormat, XmNvalueChangedCallback, setFormatCB, fileFormat); - if (window->wrapMode == CONTINUOUS_WRAP) { + if (window->editorInfo->wrapMode == CONTINUOUS_WRAP) { wrapToggle = XtVaCreateManagedWidget("addWrap", xmToggleButtonWidgetClass, formatForm, XmNlabelString, s1 = XmStringCreateSimple("Add line breaks where wrapped"), @@ -1583,7 +1586,7 @@ RemapDeleteKey(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_FILTER_TEXT)); RemapDeleteKey(XmFileSelectionBoxGetChild(fileSB, XmDIALOG_TEXT)); retVal = HandleCustomNewFileSB(fileSB, fullname, - window->filenameSet ? window->filename : NULL); + window->editorInfo->filenameSet ? window->editorInfo->filename : NULL); if (retVal != GFN_OK) SetFileDialogDefaultDirectory(savedDefaultDir); @@ -1609,7 +1612,7 @@ else sprintf(name, "Untitled_%d", i); for (w=WindowList; w!=NULL; w=w->next) - if (!strcmp(w->filename, name)) + if (!strcmp(w->editorInfo->filename, name)) break; if (w == NULL) break; @@ -1642,7 +1645,7 @@ XWindowAttributes winAttr; Boolean windowIsDestroyed = False; - if(!window->filenameSet) + if(!window->editorInfo->filenameSet) return; /* If last check was very recent, don't impact performance */ @@ -1676,20 +1679,20 @@ } /* Get the file mode and modification time */ - strcpy(fullname, window->path); - strcat(fullname, window->filename); + strcpy(fullname, window->editorInfo->path); + strcat(fullname, window->editorInfo->filename); if (stat(fullname, &statbuf) != 0) { /* Return if we've already warned the user or we can't warn him now */ - if (window->fileMissing || silent) { + if (window->editorInfo->fileMissing || silent) { return; } /* Can't stat the file -- maybe it's been deleted. The filename is now invalid */ - window->fileMissing = TRUE; - window->lastModTime = 1; - window->device = 0; - window->inode = 0; + window->editorInfo->fileMissing = TRUE; + window->editorInfo->lastModTime = 1; + window->editorInfo->device = 0; + window->editorInfo->inode = 0; /* Warn the user, if they like to be warned (Maybe this should be its own preference setting: GetPrefWarnFileDeleted()) */ @@ -1715,7 +1718,7 @@ "no longer exists.\n" "Another program may have deleted or moved it."; resp = DialogF(DF_ERR, window->shell, 2, title, body, - "Save", "Cancel", window->filename); + "Save", "Cancel", window->editorInfo->filename); break; case EACCES: /* Search permission denied for a path component. We add @@ -1726,7 +1729,7 @@ "Another program may have changed the permissions of\n" "one of its parent directories."; resp = 1 + DialogF(DF_ERR, window->shell, 1, title, body, - "Cancel", window->filename); + "Cancel", window->editorInfo->filename); break; default: /* Everything else. This hints at an internal error (eg. @@ -1737,7 +1740,7 @@ "Please make sure that no data is lost before closing\n" "this window."; resp = DialogF(DF_ERR, window->shell, 2, title, body, - "Save", "Cancel", window->filename, + "Save", "Cancel", window->editorInfo->filename, errorString()); break; } @@ -1766,7 +1769,7 @@ /* TODO: A document without a file can be locked though. */ /* Make sure that the window was not destroyed behind our back! */ if (!windowIsDestroyed) { - SET_PERM_LOCKED(window->lockReasons, False); + SET_PERM_LOCKED(window->editorInfo->lockReasons, False); UpdateWindowTitle(window); UpdateWindowReadOnly(window); } @@ -1775,12 +1778,12 @@ /* Check that the file's read-only status is still correct (but only if the file can still be opened successfully in read mode) */ - if (window->fileMode != statbuf.st_mode || - window->fileUid != statbuf.st_uid || - window->fileGid != statbuf.st_gid) { - window->fileMode = statbuf.st_mode; - window->fileUid = statbuf.st_uid; - window->fileGid = statbuf.st_gid; + if (window->editorInfo->fileMode != statbuf.st_mode || + window->editorInfo->fileUid != statbuf.st_uid || + window->editorInfo->fileGid != statbuf.st_gid) { + window->editorInfo->fileMode = statbuf.st_mode; + window->editorInfo->fileUid = statbuf.st_uid; + window->editorInfo->fileGid = statbuf.st_gid; if ((fp = fopen(fullname, "r")) != NULL) { int readOnly; fclose(fp); @@ -1793,8 +1796,8 @@ } else readOnly = TRUE; #endif - if (IS_PERM_LOCKED(window->lockReasons) != readOnly) { - SET_PERM_LOCKED(window->lockReasons, readOnly); + if (IS_PERM_LOCKED(window->editorInfo->lockReasons) != readOnly) { + SET_PERM_LOCKED(window->editorInfo->lockReasons, readOnly); UpdateWindowTitle(window); UpdateWindowReadOnly(window); } @@ -1809,31 +1812,31 @@ which is still in the process of popping down. The workaround, below, of calling XUngrabPointer is inelegant but seems to fix the problem. */ if (!silent && - ((window->lastModTime != 0 && - window->lastModTime != statbuf.st_mtime) || - window->fileMissing) ){ - window->lastModTime = 0; /* Inhibit further warnings */ - window->fileMissing = FALSE; + ((window->editorInfo->lastModTime != 0 && + window->editorInfo->lastModTime != statbuf.st_mtime) || + window->editorInfo->fileMissing) ){ + window->editorInfo->lastModTime = 0; /* Inhibit further warnings */ + window->editorInfo->fileMissing = FALSE; if (!GetPrefWarnFileMods()) return; if (GetPrefWarnRealFileMods() && !cmpWinAgainstFile(window, fullname)) { /* Contents hasn't changed. Update the modification time. */ - window->lastModTime = statbuf.st_mtime; + window->editorInfo->lastModTime = statbuf.st_mtime; return; } XUngrabPointer(XtDisplay(window->shell), timestamp); - if (window->fileChanged) + if (window->editorInfo->fileChanged) resp = DialogF(DF_WARN, window->shell, 2, "File modified externally", "%s has been modified by another program. Reload?\n\n" "WARNING: Reloading will discard changes made in this\n" - "editing session!", "Reload", "Cancel", window->filename); + "editing session!", "Reload", "Cancel", window->editorInfo->filename); else resp = DialogF(DF_WARN, window->shell, 2, "File modified externally", "%s has been modified by another\nprogram. Reload?", - "Reload", "Cancel", window->filename); + "Reload", "Cancel", window->editorInfo->filename); if (resp == 1) RevertToSaved(window); } @@ -1849,15 +1852,15 @@ char fullname[MAXPATHLEN]; struct stat statbuf; - if(!window->filenameSet) + if(!window->editorInfo->filenameSet) return FALSE; - /* if (window->lastModTime == 0) + /* if (window->editorInfo->lastModTime == 0) return FALSE; */ - strcpy(fullname, window->path); - strcat(fullname, window->filename); + strcpy(fullname, window->editorInfo->path); + strcat(fullname, window->editorInfo->filename); if (stat(fullname, &statbuf) != 0) return FALSE; - if (window->lastModTime == statbuf.st_mtime) + if (window->editorInfo->lastModTime == statbuf.st_mtime) return FALSE; if (GetPrefWarnRealFileMods() && !cmpWinAgainstFile(window, fullname)) { @@ -1872,7 +1875,7 @@ */ int CheckReadOnly(WindowInfo *window) { - if (IS_ANY_LOCKED(window->lockReasons)) { + if (IS_ANY_LOCKED(window->editorInfo->lockReasons)) { XBell(TheDisplay, 0); return True; } @@ -1972,8 +1975,8 @@ /* Modify the buffer to add wrapping */ fileString = TextGetWrapped(window->textArea, 0, - window->buffer->length, &fileLen); - BufSetAll(window->buffer, fileString); + window->editorInfo->buffer->length, &fileLen); + BufSetAll(window->editorInfo->buffer, fileString); XtFree(fileString); /* restore the insert and scroll positions of each pane */ @@ -2008,9 +2011,9 @@ struct stat statbuf; int fileLen, restLen, nRead, bufPos, rv, offset, filePos; char pendingCR = 0; - int fileFormat = window->fileFormat; + int fileFormat = window->editorInfo->fileFormat; char message[MAXPATHLEN+50]; - textBuffer *buf = window->buffer; + textBuffer *buf = window->editorInfo->buffer; FILE *fp; fp = fopen(fileName, "r"); @@ -2038,7 +2041,7 @@ /* For large files, the comparison can take a while. If it takes too long, the user should be given a clue about what is happening. */ - sprintf(message, "Comparing externally modified %s ...", window->filename); + sprintf(message, "Comparing externally modified %s ...", window->editorInfo->filename); restLen = min(PREFERRED_CMPBUF_LEN, fileLen); bufPos = 0; filePos = 0; diff -ur nedit_official/source/highlight.c nedit_mod/source/highlight.c --- nedit_official/source/highlight.c 2008-01-04 23:11:03.000000000 +0100 +++ nedit_mod/source/highlight.c 2008-03-17 23:50:02.000000000 +0100 @@ -248,7 +248,7 @@ /* Re-parse around the changed region */ if (highlightData->pass1Patterns) - incrementalReparse(highlightData, window->buffer, pos, nInserted, + incrementalReparse(highlightData, window->editorInfo->buffer, pos, nInserted, GetWindowDelimiters(window)); } @@ -282,14 +282,14 @@ /* Parse the buffer with pass 1 patterns. If there are none, initialize the style buffer to all UNFINISHED_STYLE to trigger parsing later */ - stylePtr = styleString = XtMalloc(window->buffer->length + 1); + stylePtr = styleString = XtMalloc(window->editorInfo->buffer->length + 1); if (highlightData->pass1Patterns == NULL) { - for (i=0; ibuffer->length; i++) + for (i=0; ieditorInfo->buffer->length; i++) *stylePtr++ = UNFINISHED_STYLE; } else { - stringPtr = bufString = BufAsString(window->buffer); + stringPtr = bufString = BufAsString(window->editorInfo->buffer); parseString(highlightData->pass1Patterns, &stringPtr, &stylePtr, - window->buffer->length, &prevChar, False, + window->editorInfo->buffer->length, &prevChar, False, GetWindowDelimiters(window), bufString, NULL); } *stylePtr = '\0'; @@ -1281,7 +1281,7 @@ static void handleUnparsedRegion(const WindowInfo* window, textBuffer* styleBuf, const int pos) { - textBuffer *buf = window->buffer; + textBuffer *buf = window->editorInfo->buffer; int beginParse, endParse, beginSafety, endSafety, p; windowHighlightData *highlightData = (windowHighlightData *)window->highlightData; diff -ur nedit_official/source/macro.c nedit_mod/source/macro.c --- nedit_official/source/macro.c 2007-10-04 18:04:25.000000000 +0200 +++ nedit_mod/source/macro.c 2008-03-17 23:50:02.000000000 +0100 @@ -341,6 +341,8 @@ DataValue *result, char **errMsg); static int useTabsMV(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg); +static int cloneIndexMV(WindowInfo *window, DataValue *argList, int nArgs, + DataValue *result, char **errMsg); static int modifiedMV(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg); static int languageModeMV(WindowInfo *window, DataValue *argList, int nArgs, @@ -447,7 +449,7 @@ static BuiltInSubr SpecialVars[] = {cursorMV, lineMV, columnMV, fileNameMV, filePathMV, lengthMV, selectionStartMV, selectionEndMV, selectionLeftMV, selectionRightMV, wrapMarginMV, tabDistMV, - emTabDistMV, useTabsMV, languageModeMV, modifiedMV, + emTabDistMV, useTabsMV, languageModeMV, modifiedMV, cloneIndexMV, statisticsLineMV, incSearchLineMV, showLineNumbersMV, autoIndentMV, wrapTextMV, highlightSyntaxMV, makeBackupCopyMV, incBackupMV, showMatchingMV, matchSyntaxBasedMV, @@ -465,7 +467,7 @@ "$file_name", "$file_path", "$text_length", "$selection_start", "$selection_end", "$selection_left", "$selection_right", "$wrap_margin", "$tab_dist", "$em_tab_dist", "$use_tabs", - "$language_mode", "$modified", + "$language_mode", "$modified", "$clone_index", "$statistics_line", "$incremental_search_line", "$show_line_numbers", "$auto_indent", "$wrap_text", "$highlight_syntax", "$make_backup_copy", "$incremental_backup", "$show_matching", "$match_syntax_based", @@ -1153,7 +1155,7 @@ /* If macro closed its own window, window was made empty and untitled, but close was deferred until completion. This is completion, so if the window is still empty, do the close */ - if (closeOnCompletion && !window->filenameSet && !window->fileChanged) { + if (closeOnCompletion && !window->editorInfo->filenameSet && !window->editorInfo->fileChanged) { CloseWindow(window); window = NULL; } @@ -1383,7 +1385,7 @@ /* Find out from the dialog how to repeat the command */ if (XmToggleButtonGetState(rd->inSelToggle)) { - if (!rd->forWindow->buffer->primary.selected) + if (!rd->forWindow->editorInfo->buffer->primary.selected) { DialogF(DF_WARN, rd->shell, 1, "Repeat Macro", "No selection in window to repeat within", "OK"); @@ -1878,7 +1880,7 @@ } else { /* just use the plain name as supplied */ for (w=WindowList; w != NULL; w = w->next) { - sprintf(fullname, "%s%s", w->path, w->filename); + sprintf(fullname, "%s%s", w->editorInfo->path, w->editorInfo->filename); if (!strcmp(string, fullname)) { break; } @@ -1893,7 +1895,7 @@ return False; } for (w=WindowList; w != NULL; w = w->next) { - sprintf(fullname, "%s%s", w->path, w->filename); + sprintf(fullname, "%s%s", w->editorInfo->path, w->editorInfo->filename); if (!strcmp(normalizedString, fullname)) break; } @@ -1917,8 +1919,8 @@ /* Return the name of the window */ result->tag = STRING_TAG; - AllocNString(&result->val.str, strlen(w->path)+strlen(w->filename)+1); - sprintf(result->val.str.rep, "%s%s", w->path, w->filename); + AllocNString(&result->val.str, strlen(w->editorInfo->path)+strlen(w->editorInfo->filename)+1); + sprintf(result->val.str.rep, "%s%s", w->editorInfo->path, w->editorInfo->filename); return True; } @@ -1930,7 +1932,7 @@ DataValue *result, char **errMsg) { int from, to; - textBuffer *buf = window->buffer; + textBuffer *buf = window->editorInfo->buffer; char *rangeText; /* Validate arguments and convert to int */ @@ -1967,7 +1969,7 @@ DataValue *result, char **errMsg) { int pos; - textBuffer *buf = window->buffer; + textBuffer *buf = window->editorInfo->buffer; /* Validate argument and convert it to int */ if (nArgs != 1) @@ -1996,7 +1998,7 @@ { int from, to; char stringStorage[TYPE_INT_STR_SIZE(int)], *string; - textBuffer *buf = window->buffer; + textBuffer *buf = window->editorInfo->buffer; /* Validate arguments and convert to int */ if (nArgs != 3) @@ -2014,7 +2016,7 @@ if (from > to) {int temp = from; from = to; to = temp;} /* Don't allow modifications if the window is read-only */ - if (IS_ANY_LOCKED(window->lockReasons)) { + if (IS_ANY_LOCKED(window->editorInfo->lockReasons)) { XBell(XtDisplay(window->shell), 0); result->tag = NO_TAG; return True; @@ -2026,7 +2028,7 @@ theoretically become a null. In the highly unlikely event that all of the possible substitution characters in the buffer are used up, stop the macro and tell the user of the failure */ - if (!BufSubstituteNullChars(string, strlen(string), window->buffer)) { + if (!BufSubstituteNullChars(string, strlen(string), window->editorInfo->buffer)) { *errMsg = "Too much binary data in file"; return False; } @@ -2053,7 +2055,7 @@ return False; /* Don't allow modifications if the window is read-only */ - if (IS_ANY_LOCKED(window->lockReasons)) { + if (IS_ANY_LOCKED(window->editorInfo->lockReasons)) { XBell(XtDisplay(window->shell), 0); result->tag = NO_TAG; return True; @@ -2065,13 +2067,13 @@ theoretically become a null. In the highly unlikely event that all of the possible substitution characters in the buffer are used up, stop the macro and tell the user of the failure */ - if (!BufSubstituteNullChars(string, strlen(string), window->buffer)) { + if (!BufSubstituteNullChars(string, strlen(string), window->editorInfo->buffer)) { *errMsg = "Too much binary data in file"; return False; } /* Do the replace */ - BufReplaceSelected(window->buffer, string); + BufReplaceSelected(window->editorInfo->buffer, string); result->tag = NO_TAG; return True; } @@ -2099,8 +2101,8 @@ if (selText == NULL) selText = XtNewString(""); } else { - selText = BufGetSelectionText(window->buffer); - BufUnsubstituteNullChars(selText, window->buffer); + selText = BufGetSelectionText(window->editorInfo->buffer); + BufUnsubstituteNullChars(selText, window->editorInfo->buffer); } /* Return the text as an allocated string */ @@ -2471,8 +2473,8 @@ /* we remove constness from BufAsString() result since we know searchStringMS will not modify the result */ newArgList[0].tag = STRING_TAG; - newArgList[0].val.str.rep = (char *)BufAsString(window->buffer); - newArgList[0].val.str.len = window->buffer->length; + newArgList[0].val.str.rep = (char *)BufAsString(window->editorInfo->buffer); + newArgList[0].val.str.len = window->editorInfo->buffer->length; /* copy other arguments to the new argument list */ memcpy(&newArgList[1], argList, nArgs * sizeof(DataValue)); @@ -2689,12 +2691,12 @@ end = startTmp; } if (start < 0) start = 0; - if (start > window->buffer->length) start = window->buffer->length; + if (start > window->editorInfo->buffer->length) start = window->editorInfo->buffer->length; if (end < 0) end = 0; - if (end > window->buffer->length) end = window->buffer->length; + if (end > window->editorInfo->buffer->length) end = window->editorInfo->buffer->length; /* Make the selection */ - BufSelect(window->buffer, start, end); + BufSelect(window->editorInfo->buffer, start, end); result->tag = NO_TAG; return True; } @@ -2717,7 +2719,7 @@ return False; /* Make the selection */ - BufRectSelect(window->buffer, start, end, left, right); + BufRectSelect(window->editorInfo->buffer, start, end, left, right); result->tag = NO_TAG; return True; } @@ -3441,7 +3443,7 @@ if ('\0' != defaultPath[0]) { SetFileDialogDefaultDirectory(defaultPath); } else { - SetFileDialogDefaultDirectory(window->path); + SetFileDialogDefaultDirectory(window->editorInfo->path); } /* Set filter (saving original for later) */ @@ -3566,7 +3568,7 @@ text_lines[n] = (char *)0; /* make sure this is a null-terminated table */ /* pick up the tabDist value */ - tabDist = window->buffer->tabDist; + tabDist = window->editorInfo->buffer->tabDist; /* load the table */ n = 0; @@ -4074,7 +4076,7 @@ result->tag = INT_TAG; cursorPos = TextGetCursorPos(window->lastFocus); if (!TextPosToLineAndCol(window->lastFocus, cursorPos, &line, &colNum)) - line = BufCountLines(window->buffer, 0, cursorPos) + 1; + line = BufCountLines(window->editorInfo->buffer, 0, cursorPos) + 1; result->val.n = line; return True; } @@ -4082,7 +4084,7 @@ static int columnMV(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg) { - textBuffer *buf = window->buffer; + textBuffer *buf = window->editorInfo->buffer; int cursorPos; result->tag = INT_TAG; @@ -4096,7 +4098,7 @@ DataValue *result, char **errMsg) { result->tag = STRING_TAG; - AllocNStringCpy(&result->val.str, window->filename); + AllocNStringCpy(&result->val.str, window->editorInfo->filename); return True; } @@ -4104,7 +4106,7 @@ DataValue *result, char **errMsg) { result->tag = STRING_TAG; - AllocNStringCpy(&result->val.str, window->path); + AllocNStringCpy(&result->val.str, window->editorInfo->path); return True; } @@ -4112,7 +4114,7 @@ DataValue *result, char **errMsg) { result->tag = INT_TAG; - result->val.n = window->buffer->length; + result->val.n = window->editorInfo->buffer->length; return True; } @@ -4120,8 +4122,8 @@ DataValue *result, char **errMsg) { result->tag = INT_TAG; - result->val.n = window->buffer->primary.selected ? - window->buffer->primary.start : -1; + result->val.n = window->editorInfo->buffer->primary.selected ? + window->editorInfo->buffer->primary.start : -1; return True; } @@ -4129,15 +4131,15 @@ DataValue *result, char **errMsg) { result->tag = INT_TAG; - result->val.n = window->buffer->primary.selected ? - window->buffer->primary.end : -1; + result->val.n = window->editorInfo->buffer->primary.selected ? + window->editorInfo->buffer->primary.end : -1; return True; } static int selectionLeftMV(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg) { - selection *sel = &window->buffer->primary; + selection *sel = &window->editorInfo->buffer->primary; result->tag = INT_TAG; result->val.n = sel->selected && sel->rectangular ? sel->rectStart : -1; @@ -4147,7 +4149,7 @@ static int selectionRightMV(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg) { - selection *sel = &window->buffer->primary; + selection *sel = &window->editorInfo->buffer->primary; result->tag = INT_TAG; result->val.n = sel->selected && sel->rectangular ? sel->rectEnd : -1; @@ -4195,7 +4197,7 @@ { char *res = NULL; - switch (window->indentStyle) { + switch (window->editorInfo->indentStyle) { case NO_AUTO_INDENT: res = PERM_ALLOC_STR("off"); break; @@ -4221,7 +4223,7 @@ { char *res = NULL; - switch (window->wrapMode) { + switch (window->editorInfo->wrapMode) { case NO_WRAP: res = PERM_ALLOC_STR("none"); break; @@ -4254,7 +4256,7 @@ DataValue *result, char **errMsg) { result->tag = INT_TAG; - result->val.n = window->saveOldVersion ? 1 : 0; + result->val.n = window->editorInfo->saveOldVersion ? 1 : 0; return True; } @@ -4262,7 +4264,7 @@ DataValue *result, char **errMsg) { result->tag = INT_TAG; - result->val.n = window->autoSave ? 1 : 0; + result->val.n = window->editorInfo->autoSave ? 1 : 0; return True; } @@ -4271,7 +4273,7 @@ { char *res = NULL; - switch (window->showMatchingStyle) { + switch (window->editorInfo->showMatchingStyle) { case NO_FLASH: res = PERM_ALLOC_STR(NO_FLASH_STRING); break; @@ -4296,7 +4298,7 @@ DataValue *result, char **errMsg) { result->tag = INT_TAG; - result->val.n = window->matchSyntaxBased ? 1 : 0; + result->val.n = window->editorInfo->matchSyntaxBased ? 1 : 0; return True; } @@ -4306,7 +4308,7 @@ DataValue *result, char **errMsg) { result->tag = INT_TAG; - result->val.n = window->overstrike ? 1 : 0; + result->val.n = window->editorInfo->overstrike ? 1 : 0; return True; } @@ -4314,7 +4316,7 @@ DataValue *result, char **errMsg) { result->tag = INT_TAG; - result->val.n = (IS_ANY_LOCKED(window->lockReasons)) ? 1 : 0; + result->val.n = (IS_ANY_LOCKED(window->editorInfo->lockReasons)) ? 1 : 0; return True; } @@ -4322,7 +4324,7 @@ DataValue *result, char **errMsg) { result->tag = INT_TAG; - result->val.n = (IS_USER_LOCKED(window->lockReasons)) ? 1 : 0; + result->val.n = (IS_USER_LOCKED(window->editorInfo->lockReasons)) ? 1 : 0; return True; } @@ -4331,7 +4333,7 @@ { char *res = NULL; - switch (window->fileFormat) { + switch (window->editorInfo->fileFormat) { case UNIX_FILE_FORMAT: res = PERM_ALLOC_STR("unix"); break; @@ -4468,7 +4470,7 @@ DataValue *result, char **errMsg) { result->tag = INT_TAG; - result->val.n = window->buffer->tabDist; + result->val.n = window->editorInfo->buffer->tabDist; return True; } @@ -4487,7 +4489,15 @@ DataValue *result, char **errMsg) { result->tag = INT_TAG; - result->val.n = window->buffer->useTabs; + result->val.n = window->editorInfo->buffer->useTabs; + return True; +} + +static int cloneIndexMV(WindowInfo *window, DataValue *argList, int nArgs, + DataValue *result, char **errMsg) +{ + result->tag = INT_TAG; + result->val.n = GetCloneIndex(window); return True; } @@ -4495,7 +4505,7 @@ DataValue *result, char **errMsg) { result->tag = INT_TAG; - result->val.n = window->fileChanged; + result->val.n = window->editorInfo->fileChanged; return True; } @@ -4532,7 +4542,7 @@ static int rangesetListMV(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg) { - RangesetTable *rangesetTable = window->buffer->rangesetTable; + RangesetTable *rangesetTable = window->editorInfo->buffer->rangesetTable; unsigned char *rangesetList; char *allocIndexStr; char indexStr[TYPE_INT_STR_SIZE(int)] ; @@ -4601,14 +4611,14 @@ DataValue element; char indexStr[TYPE_INT_STR_SIZE(int)], *allocIndexStr; - RangesetTable *rangesetTable = window->buffer->rangesetTable; + RangesetTable *rangesetTable = window->editorInfo->buffer->rangesetTable; if (nArgs > 1) return wrongNArgsErr(errMsg); if (rangesetTable == NULL) { - window->buffer->rangesetTable = rangesetTable = - RangesetTableAlloc(window->buffer); + window->editorInfo->buffer->rangesetTable = rangesetTable = + RangesetTableAlloc(window->editorInfo->buffer); } if (nArgs == 0) { @@ -4652,7 +4662,7 @@ static int rangesetDestroyMS(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg) { - RangesetTable *rangesetTable = window->buffer->rangesetTable; + RangesetTable *rangesetTable = window->editorInfo->buffer->rangesetTable; DataValue *array; DataValue element; char keyString[TYPE_INT_STR_SIZE(int)]; @@ -4719,7 +4729,7 @@ Rangeset *rangeset; int label; char *name, *rangeset_name; - RangesetTable *rangesetTable = window->buffer->rangesetTable; + RangesetTable *rangesetTable = window->editorInfo->buffer->rangesetTable; unsigned char *rangesetList; char *allocIndexStr; char indexStr[TYPE_INT_STR_SIZE(int)] ; @@ -4780,7 +4790,7 @@ static int rangesetAddMS(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg) { - textBuffer *buffer = window->buffer; + textBuffer *buffer = window->editorInfo->buffer; RangesetTable *rangesetTable = buffer->rangesetTable; Rangeset *targetRangeset, *sourceRangeset; int start, end, isRect, rectStart, rectEnd, maxpos, index; @@ -4879,7 +4889,7 @@ static int rangesetSubtractMS(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg) { - textBuffer *buffer = window->buffer; + textBuffer *buffer = window->editorInfo->buffer; RangesetTable *rangesetTable = buffer->rangesetTable; Rangeset *targetRangeset, *sourceRangeset; int start, end, isRect, rectStart, rectEnd, maxpos; @@ -4959,7 +4969,7 @@ DataValue *result, char **errMsg) { - RangesetTable *rangesetTable = window->buffer->rangesetTable; + RangesetTable *rangesetTable = window->editorInfo->buffer->rangesetTable; Rangeset *rangeset; int label = 0; @@ -4998,7 +5008,7 @@ static int rangesetInfoMS(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg) { - RangesetTable *rangesetTable = window->buffer->rangesetTable; + RangesetTable *rangesetTable = window->editorInfo->buffer->rangesetTable; Rangeset *rangeset = NULL; int count, defined; char *color, *name, *mode; @@ -5064,7 +5074,7 @@ static int rangesetRangeMS(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg) { - textBuffer *buffer = window->buffer; + textBuffer *buffer = window->editorInfo->buffer; RangesetTable *rangesetTable = buffer->rangesetTable; Rangeset *rangeset; int start, end, dummy, rangeIndex, ok; @@ -5130,7 +5140,7 @@ static int rangesetIncludesPosMS(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg) { - textBuffer *buffer = window->buffer; + textBuffer *buffer = window->editorInfo->buffer; RangesetTable *rangesetTable = buffer->rangesetTable; Rangeset *rangeset; int pos, rangeIndex, maxpos; @@ -5185,7 +5195,7 @@ int nArgs, DataValue *result, char **errMsg) { char stringStorage[1][TYPE_INT_STR_SIZE(int)]; - textBuffer *buffer = window->buffer; + textBuffer *buffer = window->editorInfo->buffer; RangesetTable *rangesetTable = buffer->rangesetTable; Rangeset *rangeset; char *color_name; @@ -5231,7 +5241,7 @@ int nArgs, DataValue *result, char **errMsg) { char stringStorage[1][TYPE_INT_STR_SIZE(int)]; - textBuffer *buffer = window->buffer; + textBuffer *buffer = window->editorInfo->buffer; RangesetTable *rangesetTable = buffer->rangesetTable; Rangeset *rangeset; char *name; @@ -5277,7 +5287,7 @@ int nArgs, DataValue *result, char **errMsg) { char stringStorage[1][TYPE_INT_STR_SIZE(int)]; - textBuffer *buffer = window->buffer; + textBuffer *buffer = window->editorInfo->buffer; RangesetTable *rangesetTable = buffer->rangesetTable; Rangeset *rangeset; char *update_fn_name; @@ -5495,7 +5505,7 @@ { int patCode; int bufferPos; - textBuffer *buf = window->buffer; + textBuffer *buf = window->editorInfo->buffer; /* Validate number of arguments */ if (nArgs != 1) { @@ -5637,7 +5647,7 @@ DataValue *result, char **errMsg) { int bufferPos = -1; - textBuffer *buffer = window->buffer; + textBuffer *buffer = window->editorInfo->buffer; int patCode = 0; /* Begin of building the result. */ diff -ur nedit_official/source/menu.c nedit_mod/source/menu.c --- nedit_official/source/menu.c 2008-01-04 23:11:03.000000000 +0100 +++ nedit_mod/source/menu.c 2008-03-17 23:50:02.000000000 +0100 @@ -305,6 +305,8 @@ static void showTipAP(Widget w, XEvent *event, String *args, Cardinal *nArgs); static void splitPaneAP(Widget w, XEvent *event, String *args, Cardinal *nArgs); +static void cloneDocumentAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs); static void detachDocumentDialogAP(Widget w, XEvent *event, String *args, Cardinal *nArgs); static void detachDocumentAP(Widget w, XEvent *event, String *args, @@ -523,6 +525,7 @@ {"split_pane", splitPaneAP}, {"close-pane", closePaneAP}, {"close_pane", closePaneAP}, + {"clone_document", cloneDocumentAP}, {"detach_document", detachDocumentAP}, {"detach_document_dialog", detachDocumentDialogAP}, {"move_document_dialog", moveDocumentDialogAP}, @@ -761,7 +764,7 @@ window->overtypeModeItem = createMenuToggle(menuPane, "overtype", "Overtype", 'O', doActionCB, "set_overtype_mode", False, SHORT); window->readOnlyItem = createMenuToggle(menuPane, "readOnly", "Read Only", - 'y', doActionCB, "set_locked", IS_USER_LOCKED(window->lockReasons), FULL); + 'y', doActionCB, "set_locked", IS_USER_LOCKED(window->editorInfo->lockReasons), FULL); #endif /* @@ -1082,24 +1085,24 @@ subPane = createMenu(menuPane, "autoIndent", "Auto Indent", 'A', NULL, FULL); window->autoIndentOffItem = createMenuRadioToggle(subPane, "off", "Off", - 'O', autoIndentOffCB, window, window->indentStyle == NO_AUTO_INDENT, + 'O', autoIndentOffCB, window, window->editorInfo->indentStyle == NO_AUTO_INDENT, SHORT); window->autoIndentItem = createMenuRadioToggle(subPane, "on", "On", 'n', - autoIndentCB, window, window->indentStyle == AUTO_INDENT, SHORT); + autoIndentCB, window, window->editorInfo->indentStyle == AUTO_INDENT, SHORT); window->smartIndentItem = createMenuRadioToggle(subPane, "smart", "Smart", - 'S', smartIndentCB, window, window->indentStyle == SMART_INDENT, + 'S', smartIndentCB, window, window->editorInfo->indentStyle == SMART_INDENT, SHORT); subPane = createMenu(menuPane, "wrap", "Wrap", 'W', NULL, FULL); window->noWrapItem = createMenuRadioToggle(subPane, "none", "None", 'N', noWrapCB, window, - window->wrapMode==NO_WRAP, SHORT); + window->editorInfo->wrapMode==NO_WRAP, SHORT); window->newlineWrapItem = createMenuRadioToggle(subPane, "autoNewlineWrap", "Auto Newline", 'A', newlineWrapCB, window, - window->wrapMode==NEWLINE_WRAP, SHORT); + window->editorInfo->wrapMode==NEWLINE_WRAP, SHORT); window->continuousWrapItem = createMenuRadioToggle(subPane, "continuousWrap", "Continuous", 'C', continuousWrapCB, window, - window->wrapMode==CONTINUOUS_WRAP, SHORT); + window->editorInfo->wrapMode==CONTINUOUS_WRAP, SHORT); createMenuSeparator(subPane, "sep1", SHORT); createMenuItem(subPane, "wrapMargin", "Wrap Margin...", 'W', wrapMarginCB, window, SHORT); @@ -1115,34 +1118,34 @@ #ifndef VMS window->saveLastItem = createMenuToggle(menuPane, "makeBackupCopy", "Make Backup Copy (*.bck)", 'e', preserveCB, window, - window->saveOldVersion, SHORT); + window->editorInfo->saveOldVersion, SHORT); #endif window->autoSaveItem = createMenuToggle(menuPane, "incrementalBackup", - "Incremental Backup", 'B', autoSaveCB, window, window->autoSave, + "Incremental Backup", 'B', autoSaveCB, window, window->editorInfo->autoSave, SHORT); subPane = createMenu(menuPane, "showMatching", "Show Matching (..)", 'M', NULL, FULL); window->showMatchingOffItem = createMenuRadioToggle(subPane, "off", "Off", - 'O', showMatchingOffCB, window, window->showMatchingStyle == NO_FLASH, + 'O', showMatchingOffCB, window, window->editorInfo->showMatchingStyle == NO_FLASH, SHORT); window->showMatchingDelimitItem = createMenuRadioToggle(subPane, "delimiter", "Delimiter", 'D', showMatchingDelimitCB, window, - window->showMatchingStyle == FLASH_DELIMIT, SHORT); + window->editorInfo->showMatchingStyle == FLASH_DELIMIT, SHORT); window->showMatchingRangeItem = createMenuRadioToggle(subPane, "range", "Range", 'R', showMatchingRangeCB, window, - window->showMatchingStyle == FLASH_RANGE, SHORT); + window->editorInfo->showMatchingStyle == FLASH_RANGE, SHORT); createMenuSeparator(subPane, "sep", SHORT); window->matchSyntaxBasedItem = createMenuToggle(subPane, "matchSyntax", "Syntax Based", 'S', matchSyntaxBasedCB, window, - window->matchSyntaxBased, SHORT); + window->editorInfo->matchSyntaxBased, SHORT); #ifndef SGI_CUSTOM createMenuSeparator(menuPane, "sep2", SHORT); window->overtypeModeItem = createMenuToggle(menuPane, "overtype", "Overtype", 'O', doActionCB, "set_overtype_mode", False, SHORT); window->readOnlyItem = createMenuToggle(menuPane, "readOnly", "Read Only", - 'y', doActionCB, "set_locked", IS_USER_LOCKED(window->lockReasons), FULL); + 'y', doActionCB, "set_locked", IS_USER_LOCKED(window->editorInfo->lockReasons), FULL); #endif #ifndef VMS @@ -1211,8 +1214,11 @@ "Close Pane", 'C', doActionCB, "close_pane", SHORT); XtVaSetValues(window->closePaneItem, XmNuserData, PERMANENT_MENU_ITEM,NULL); XtSetSensitive(window->closePaneItem, False); + XtVaSetValues(btn, XmNuserData, PERMANENT_MENU_ITEM, NULL); btn = createMenuSeparator(menuPane, "sep01", SHORT); + btn = createMenuItem(menuPane, "cloneTab", + "Clone Tab", 'o', doActionCB, "clone_document", SHORT); XtVaSetValues(btn, XmNuserData, PERMANENT_MENU_ITEM, NULL); window->detachDocumentItem = createMenuItem(menuPane, "detachBuffer", "Detach Tab", 'D', doActionCB, "detach_document", SHORT); @@ -2735,7 +2741,7 @@ } } - EditNewFile(openInTab? window : NULL, NULL, False, NULL, window->path); + EditNewFile(openInTab? window : NULL, NULL, False, NULL, window->editorInfo->path); CheckCloseDim(); } @@ -2749,14 +2755,14 @@ WindowInfo *window = WidgetToWindow(w); EditNewFile(GetPrefOpenInTab()? NULL : window, NULL, False, NULL, - window->path); + window->editorInfo->path); CheckCloseDim(); } static void newTabAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) { WindowInfo *window = WidgetToWindow(w); - EditNewFile(window, NULL, False, NULL, window->path); + EditNewFile(window, NULL, False, NULL, window->editorInfo->path); CheckCloseDim(); } @@ -2845,7 +2851,7 @@ &fileFormat, &addWrap); if (response != GFN_OK) return; - window->fileFormat = fileFormat; + window->editorInfo->fileFormat = fileFormat; params[0] = fullname; params[1] = "wrapped"; XtCallActionProc(window->lastFocus, "save_as", event, params, addWrap?2:1); @@ -2868,16 +2874,16 @@ int b; /* re-reading file is irreversible, prompt the user first */ - if (window->fileChanged) + if (window->editorInfo->fileChanged) { b = DialogF(DF_QUES, window->shell, 2, "Discard Changes", - "Discard changes to\n%s%s?", "OK", "Cancel", window->path, - window->filename); + "Discard changes to\n%s%s?", "OK", "Cancel", window->editorInfo->path, + window->editorInfo->filename); } else { b = DialogF(DF_QUES, window->shell, 2, "Reload File", - "Re-load file\n%s%s?", "Re-read", "Cancel", window->path, - window->filename); + "Re-load file\n%s%s?", "Re-read", "Cancel", window->editorInfo->path, + window->editorInfo->filename); } if (b != 1) @@ -3085,7 +3091,10 @@ lineLen = 0; strcpy(ptr, "Editing: "); ptr += 9; lineLen += 9; for (win=WindowList; win!=NULL; win=win->next) { - sprintf(filename, "%s%s", win->filename, win->fileChanged? "*": ""); + if (win->editorInfo->master != win) + continue; /* skip clones */ + + sprintf(filename, "%s%s", win->editorInfo->filename, win->editorInfo->fileChanged? "*": ""); title = filename; titleLen = strlen(title); if (ptr - exitMsg + titleLen + 30 >= DF_MAX_MSG_LENGTH) { @@ -3142,14 +3151,14 @@ if (CheckReadOnly(window)) return; - BufRemoveSelected(window->buffer); + BufRemoveSelected(window->editorInfo->buffer); } static void selAllAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) { WindowInfo *window = WidgetToWindow(w); - BufSelect(window->buffer, 0, window->buffer->length); + BufSelect(window->editorInfo->buffer, 0, window->editorInfo->buffer->length); } static void shiftLeftAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) @@ -3498,6 +3507,14 @@ } } +static void cloneDocumentAP(Widget w, XEvent *event, String *args, + Cardinal *nArgs) +{ + WindowInfo *window = WidgetToWindow(w); + + CreateCloneWindow(window); +} + static void detachDocumentDialogAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) { @@ -3508,7 +3525,7 @@ return; resp = DialogF(DF_QUES, window->shell, 2, "Detach %s?", - "Detach", "Cancel", window->filename); + "Detach", "Cancel", window->editorInfo->filename); if (resp == 1) DetachDocument(window); @@ -3604,7 +3621,7 @@ charCodeString[1] = '\0'; params[0] = (char *)charCodeString; - if (!BufSubstituteNullChars((char *)charCodeString, 1, window->buffer)) + if (!BufSubstituteNullChars((char *)charCodeString, 1, window->editorInfo->buffer)) { DialogF(DF_ERR, window->shell, 1, "Error", "Too much binary data", "OK"); @@ -3626,7 +3643,7 @@ if (CheckReadOnly(window)) return; - if (!window->buffer->primary.selected) { + if (!window->editorInfo->buffer->primary.selected) { XBell(TheDisplay, 0); return; } @@ -4100,13 +4117,13 @@ WindowInfo *window = WidgetToWindow(w); Boolean newState; - ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->saveOldVersion, "set_make_backup_copy"); + ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->editorInfo->saveOldVersion, "set_make_backup_copy"); #ifndef VMS if (IsTopDocument(window)) XmToggleButtonSetState(window->saveLastItem, newState, False); #endif - window->saveOldVersion = newState; + window->editorInfo->saveOldVersion = newState; } static void setIncrementalBackupAP(Widget w, XEvent *event, String *args, @@ -4115,11 +4132,11 @@ WindowInfo *window = WidgetToWindow(w); Boolean newState; - ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->autoSave, "set_incremental_backup"); + ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->editorInfo->autoSave, "set_incremental_backup"); if (IsTopDocument(window)) XmToggleButtonSetState(window->autoSaveItem, newState, False); - window->autoSave = newState; + window->editorInfo->autoSave = newState; } static void setShowMatchingAP(Widget w, XEvent *event, String *args, @@ -4162,11 +4179,11 @@ WindowInfo *window = WidgetToWindow(w); Boolean newState; - ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->matchSyntaxBased, "set_match_syntax_based"); + ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->editorInfo->matchSyntaxBased, "set_match_syntax_based"); if (IsTopDocument(window)) XmToggleButtonSetState(window->matchSyntaxBasedItem, newState, False); - window->matchSyntaxBased = newState; + window->editorInfo->matchSyntaxBased = newState; } static void setOvertypeModeAP(Widget w, XEvent *event, String *args, @@ -4174,15 +4191,18 @@ { WindowInfo *window = WidgetToWindow(w); Boolean newState; + WindowInfo *win; if (window == NULL) return; - ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->overstrike, "set_overtype_mode"); + ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->editorInfo->overstrike, "set_overtype_mode"); - if (IsTopDocument(window)) - XmToggleButtonSetState(window->overtypeModeItem, newState, False); - SetOverstrike(window, newState); + for(win = window->editorInfo->master; win; win = win->nextSlave) { + if (IsTopDocument(win)) + XmToggleButtonSetState(win->overtypeModeItem, newState, False); + SetOverstrike(win, newState); + } } static void setLockedAP(Widget w, XEvent *event, String *args, @@ -4191,11 +4211,11 @@ WindowInfo *window = WidgetToWindow(w); Boolean newState; - ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, IS_USER_LOCKED(window->lockReasons), "set_locked"); + ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, IS_USER_LOCKED(window->editorInfo->lockReasons), "set_locked"); - SET_USER_LOCKED(window->lockReasons, newState); + SET_USER_LOCKED(window->editorInfo->lockReasons, newState); if (IsTopDocument(window)) - XmToggleButtonSetState(window->readOnlyItem, IS_ANY_LOCKED(window->lockReasons), False); + XmToggleButtonSetState(window->readOnlyItem, IS_ANY_LOCKED(window->editorInfo->lockReasons), False); UpdateWindowTitle(window); UpdateWindowReadOnly(window); } @@ -4253,9 +4273,9 @@ WindowInfo *window = WidgetToWindow(w); Boolean newState; - ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->buffer->useTabs, "set_use_tabs"); + ACTION_BOOL_PARAM_OR_TOGGLE(newState, *nArgs, args, window->editorInfo->buffer->useTabs, "set_use_tabs"); - window->buffer->useTabs = newState; + window->editorInfo->buffer->useTabs = newState; } static void setFontsAP(Widget w, XEvent *event, String *args, @@ -4442,7 +4462,7 @@ if (WindowList == NULL) return; if (WindowList->next==NULL && - !WindowList->filenameSet && !WindowList->fileChanged) { + !WindowList->editorInfo->filenameSet && !WindowList->editorInfo->fileChanged) { XtSetSensitive(WindowList->closeItem, FALSE); return; } @@ -4560,15 +4580,22 @@ static char* getWindowsMenuEntry(const WindowInfo* window) { - static char fullTitle[MAXPATHLEN * 2 + 3+ 1]; + static char fullTitle[MAXPATHLEN * 2 + 3+ 1 + 4]; + char cloneIndex[10]; + + if (GetCloneIndex(window) > 0) { + sprintf(cloneIndex, "<%d>", GetCloneIndex(window)); + } else { + cloneIndex[0] = '\0'; + } - sprintf(fullTitle, "%s%s", window->filename, - window->fileChanged? "*" : ""); + sprintf(fullTitle, "%s%s%s", window->editorInfo->filename, cloneIndex, + window->editorInfo->fileChanged? "*" : ""); - if (GetPrefShowPathInWindowsMenu() && window->filenameSet) + if (GetPrefShowPathInWindowsMenu() && window->editorInfo->filenameSet) { strcat(fullTitle, " - "); - strcat(fullTitle, window->path); + strcat(fullTitle, window->editorInfo->path); } return(fullTitle); @@ -5232,14 +5259,14 @@ const WindowInfo *a = *((WindowInfo**)windowA); const WindowInfo *b = *((WindowInfo**)windowB); /* Untitled first */ - rc = a->filenameSet == b->filenameSet ? 0 : - a->filenameSet && !b->filenameSet ? 1 : -1; + rc = a->editorInfo->filenameSet == b->editorInfo->filenameSet ? 0 : + a->editorInfo->filenameSet && !b->editorInfo->filenameSet ? 1 : -1; if (rc != 0) return rc; - rc = strcmp(a->filename, b->filename); + rc = strcmp(a->editorInfo->filename, b->editorInfo->filename); if (rc != 0) return rc; - rc = strcmp(a->path, b->path); + rc = strcmp(a->editorInfo->path, b->editorInfo->path); return rc; } @@ -5277,6 +5304,8 @@ createMenuItem(menu, "new", "New Tab", 0, doTabActionCB, "new_tab", SHORT); createMenuItem(menu, "close", "Close Tab", 0, doTabActionCB, "close", SHORT); createMenuSeparator(menu, "sep1", SHORT); + createMenuItem(menu, "cloneTab", "Clone Tab", 0, doTabActionCB, + "clone_document", SHORT); window->contextDetachDocumentItem = createMenuItem(menu, "detach", "Detach Tab", 0, doTabActionCB, "detach_document", SHORT); XtSetSensitive(window->contextDetachDocumentItem, False); diff -ur nedit_official/source/nedit.h nedit_mod/source/nedit.h --- nedit_official/source/nedit.h 2008-01-04 23:11:03.000000000 +0100 +++ nedit_mod/source/nedit.h 2008-03-17 23:50:02.000000000 +0100 @@ -255,6 +255,59 @@ UserMenuList ubmcMenuList; /* list of all background menu items */ } UserBGMenuCache; +/* The EditorInfo structure hold the information related to + a document/file. It is used to support document/window cloning, + so that multiple documents/windows may be created at the same + session, all access the same underlying buffer content. +*/ +typedef struct _EditorInfo { + char filename[MAXPATHLEN]; /* name component of file being edited*/ + char path[MAXPATHLEN]; /* path component of file being edited*/ + unsigned fileMode; /* permissions of file being edited */ + uid_t fileUid; /* last recorded user id of the file */ + gid_t fileGid; /* last recorded group id of the file */ + int fileFormat; /* whether to save the file straight + (Unix format), or convert it to + MS DOS style with \r\n line breaks */ + time_t lastModTime; /* time of last modification to file */ + dev_t device; /* device where the file resides */ + ino_t inode; /* file's inode */ + 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? */ + int lockReasons; /* all ways a file can be locked */ + Boolean autoSave; /* is autosave turned on? */ + Boolean saveOldVersion; /* keep old version in filename.bck */ + Boolean overstrike; /* is overstrike mode turned on ? */ + Boolean fileMissing; /* is the window's file gone? */ + char showMatchingStyle; /* How to show matching parens: + NO_FLASH, FLASH_DELIMIT, or + FLASH_RANGE */ + char matchSyntaxBased; /* Use syntax info to show matching */ + 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 fileClosedAtom; /* Atom used to tell nc that the file is closed */ + struct _WindowInfo *master; /* used to identify a master document + where the clones share the data */ +} EditorInfo; + /* The WindowInfo structure holds the information on a Document. A number of 'tabbed' documents may reside within a shell window, hence some of its members are of 'shell-level'; namely the find/replace dialogs, the @@ -274,6 +327,9 @@ */ typedef struct _WindowInfo { struct _WindowInfo *next; + struct _WindowInfo *nextSlave; /* next clone */ + EditorInfo *editorInfo; /* one copy of buffer for all clones */ + Widget shell; /* application shell of window */ Widget mainWin; /* main window of shell */ Widget splitPane; /* paned win. for splitting text area */ @@ -451,28 +507,8 @@ short menus on and off */ int nToggleShortItems; #endif - char filename[MAXPATHLEN]; /* name component of file being edited*/ - char path[MAXPATHLEN]; /* path component of file being edited*/ - unsigned fileMode; /* permissions of file being edited */ - uid_t fileUid; /* last recorded user id of the file */ - gid_t fileGid; /* last recorded group id of the file */ - int fileFormat; /* whether to save the file straight - (Unix format), or convert it to - MS DOS style with \r\n line breaks */ - time_t lastModTime; /* time of last modification to file */ - dev_t device; /* device where the file resides */ - ino_t inode; /* file's inode */ - 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 */ char italicFontName[MAX_FONT_LEN]; char boldFontName[MAX_FONT_LEN]; @@ -481,27 +517,8 @@ XFontStruct *italicFontStruct; /* fontStructs for highlighting fonts */ XFontStruct *boldFontStruct; 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 fileMissing; /* is the window's file gone? */ - int lockReasons; /* all ways a file can be locked */ - 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 ? */ - char showMatchingStyle; /* How to show matching parens: - NO_FLASH, FLASH_DELIMIT, or - FLASH_RANGE */ - char matchSyntaxBased; /* Use syntax info to show matching */ Boolean showStats; /* is stats line supposed to be shown */ Boolean showISearchLine; /* is incr. search line to be shown */ Boolean showLineNumbers; /* is the line number display shown */ @@ -512,7 +529,6 @@ and shell command executing modes */ char *modeMessage; /* stats line banner content for learn and shell command executing modes */ - Boolean ignoreModify; /* ignore modifications to text area */ Boolean windowMenuValid; /* is window menu up to date? */ int rHistIndex, fHistIndex; /* history placeholders for */ int iSearchHistIndex; /* find and replace dialogs */ @@ -525,8 +541,6 @@ 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 */ - Atom fileClosedAtom; /* Atom used to tell nc that the file is closed */ int languageMode; /* identifies language mode currently selected in the window */ Boolean multiFileReplSelected; /* selected during last multi-window diff -ur nedit_official/source/preferences.c nedit_mod/source/preferences.c --- nedit_official/source/preferences.c 2008-01-14 21:39:20.000000000 +0100 +++ nedit_mod/source/preferences.c 2008-03-17 23:50:02.000000000 +0100 @@ -2542,8 +2542,8 @@ tabDist = GetPrefTabDist(PLAIN_LANGUAGE_MODE); } else { XtVaGetValues(forWindow->textArea, textNemulateTabs, &emTabDist, NULL); - useTabs = forWindow->buffer->useTabs; - tabDist = BufGetTabDistance(forWindow->buffer); + useTabs = forWindow->editorInfo->buffer->useTabs; + tabDist = BufGetTabDistance(forWindow->editorInfo->buffer); } emulate = emTabDist != 0; SetIntText(TabDistText, tabDist); @@ -2647,7 +2647,7 @@ /* setTabDist(window, tabDist); setEmTabDist(window, emTabDist); - window->buffer->useTabs = useTabs; + window->editorInfo->buffer->useTabs = useTabs; */ } DoneWithTabsDialog = True; @@ -4448,25 +4448,25 @@ /* Decide on desired values for language-specific parameters. If a parameter was set to its default value, set it to the new default, otherwise, leave it alone */ - wrapModeIsDef = window->wrapMode == GetPrefWrap(oldMode); - tabDistIsDef = BufGetTabDistance(window->buffer) == GetPrefTabDist(oldMode); + wrapModeIsDef = window->editorInfo->wrapMode == GetPrefWrap(oldMode); + tabDistIsDef = BufGetTabDistance(window->editorInfo->buffer) == GetPrefTabDist(oldMode); XtVaGetValues(window->textArea, textNemulateTabs, &oldEmTabDist, NULL); emTabDistIsDef = oldEmTabDist == GetPrefEmTabDist(oldMode); - indentStyleIsDef = window->indentStyle == GetPrefAutoIndent(oldMode) || + indentStyleIsDef = window->editorInfo->indentStyle == GetPrefAutoIndent(oldMode) || (GetPrefAutoIndent(oldMode) == SMART_INDENT && - window->indentStyle == AUTO_INDENT && + window->editorInfo->indentStyle == AUTO_INDENT && !SmartIndentMacrosAvailable(LanguageModeName(oldMode))); highlightIsDef = window->highlightSyntax == GetPrefHighlightSyntax() || (GetPrefHighlightSyntax() && FindPatternSet(LanguageModeName(oldMode)) == NULL); wrapMode = wrapModeIsDef || forceDefaults ? - GetPrefWrap(mode) : window->wrapMode; + GetPrefWrap(mode) : window->editorInfo->wrapMode; tabDist = tabDistIsDef || forceDefaults ? - GetPrefTabDist(mode) : BufGetTabDistance(window->buffer); + GetPrefTabDist(mode) : BufGetTabDistance(window->editorInfo->buffer); emTabDist = emTabDistIsDef || forceDefaults ? GetPrefEmTabDist(mode) : oldEmTabDist; indentStyle = indentStyleIsDef || forceDefaults ? - GetPrefAutoIndent(mode) : window->indentStyle; + GetPrefAutoIndent(mode) : window->editorInfo->indentStyle; highlight = highlightIsDef || forceDefaults ? GetPrefHighlightSyntax() : window->highlightSyntax; @@ -4494,9 +4494,9 @@ StartHighlighting(window, False); /* Force a change of smart indent macros (SetAutoIndent will re-start) */ - if (window->indentStyle == SMART_INDENT) { + if (window->editorInfo->indentStyle == SMART_INDENT) { EndSmartIndent(window); - window->indentStyle = AUTO_INDENT; + window->editorInfo->indentStyle = AUTO_INDENT; } /* set requested wrap, indent, and tabs */ @@ -4528,7 +4528,7 @@ /*... look for an explicit mode statement first */ /* Do a regular expression search on for recognition pattern */ - first200 = BufGetRange(window->buffer, 0, 200); + first200 = BufGetRange(window->editorInfo->buffer, 0, 200); for (i=0; irecognitionExpr != NULL) { if (SearchString(first200, LanguageModes[i]->recognitionExpr, @@ -4545,13 +4545,13 @@ /* Look at file extension ("@@/" starts a ClearCase version extended path, which gets appended after the file extension, and therefore must be stripped off to recognize the extension to make ClearCase users happy) */ - fileNameLen = strlen(window->filename); + fileNameLen = strlen(window->editorInfo->filename); #ifdef VMS - if (strchr(window->filename, ';') != NULL) - fileNameLen = strchr(window->filename, ';') - window->filename; + if (strchr(window->editorInfo->filename, ';') != NULL) + fileNameLen = strchr(window->editorInfo->filename, ';') - window->editorInfo->filename; #else - if ((versionExtendedPath = GetClearCaseVersionExtendedPath(window->filename)) != NULL) - fileNameLen = versionExtendedPath - window->filename; + if ((versionExtendedPath = GetClearCaseVersionExtendedPath(window->editorInfo->filename)) != NULL) + fileNameLen = versionExtendedPath - window->editorInfo->filename; #endif for (i=0; inExtensions; j++) { @@ -4560,10 +4560,10 @@ start = fileNameLen - extLen; #if defined(__VMS) && (__VMS_VER >= 70200000) /* VMS v7.2 has case-preserving filenames */ - if (start >= 0 && !strncasecmp(&window->filename[start], ext, extLen)) + if (start >= 0 && !strncasecmp(&window->editorInfo->filename[start], ext, extLen)) return i; #else - if (start >= 0 && !strncmp(&window->filename[start], ext, extLen)) + if (start >= 0 && !strncmp(&window->editorInfo->filename[start], ext, extLen)) return i; #endif } diff -ur nedit_official/source/search.c nedit_mod/source/search.c --- nedit_official/source/search.c 2008-03-09 13:07:19.000000000 +0100 +++ nedit_mod/source/search.c 2008-03-17 23:50:02.000000000 +0100 @@ -396,7 +396,7 @@ int lineWidth; textDisp *textD; - if (!BufGetSelectionPos(window->buffer, &selStart, &selEnd, &isRect, + if (!BufGetSelectionPos(window->editorInfo->buffer, &selStart, &selEnd, &isRect, &rectStart, &rectEnd)) return FALSE; @@ -414,13 +414,13 @@ we also assume a multi-line selection. */ - lineStartStart = BufStartOfLine(window->buffer, selStart); - lineStartEnd = BufStartOfLine(window->buffer, selEnd); + lineStartStart = BufStartOfLine(window->editorInfo->buffer, selStart); + lineStartEnd = BufStartOfLine(window->editorInfo->buffer, selEnd); /* If the line starts differ, we have a "\n" in between. */ if (lineStartStart != lineStartEnd ) return TRUE; - if (window->wrapMode != CONTINUOUS_WRAP) + if (window->editorInfo->wrapMode != CONTINUOUS_WRAP) return FALSE; /* Same line */ /* Estimate the number of characters on a line */ @@ -710,7 +710,7 @@ form = CreateFormDialog(parent, "replaceDialog", args, argcnt); XtVaSetValues(form, XmNshadowThickness, 0, NULL); if (GetPrefKeepSearchDlogs()) { - sprintf(title, "Replace/Find (in %s)", window->filename); + sprintf(title, "Replace/Find (in %s)", window->editorInfo->filename); XtVaSetValues(XtParent(form), XmNtitle, title, NULL); } else XtVaSetValues(XtParent(form), XmNtitle, "Replace/Find", NULL); @@ -1200,7 +1200,7 @@ form = CreateFormDialog(parent, "findDialog", args, argcnt); XtVaSetValues(form, XmNshadowThickness, 0, NULL); if (GetPrefKeepSearchDlogs()) { - sprintf(title, "Find (in %s)", window->filename); + sprintf(title, "Find (in %s)", window->editorInfo->filename); XtVaSetValues(XtParent(form), XmNtitle, title, NULL); } else XtVaSetValues(XtParent(form), XmNtitle, "Find", NULL); @@ -1696,7 +1696,7 @@ window = WidgetToWindow(w); if (XmToggleButtonGetState(w)) { - sprintf(title, "Replace/Find (in %s)", window->filename); + sprintf(title, "Replace/Find (in %s)", window->editorInfo->filename); XtVaSetValues(XtParent(window->replaceDlog), XmNtitle, title, NULL); } else XtVaSetValues(XtParent(window->replaceDlog), XmNtitle, "Replace/Find", NULL); @@ -1708,7 +1708,7 @@ window = WidgetToWindow(w); if (XmToggleButtonGetState(w)) { - sprintf(title, "Find (in %s)", window->filename); + sprintf(title, "Find (in %s)", window->editorInfo->filename); XtVaSetValues(XtParent(window->findDlog), XmNtitle, title, NULL); } else XtVaSetValues(XtParent(window->findDlog), XmNtitle, "Find", NULL); @@ -1802,8 +1802,8 @@ */ static int compareWindowNames(const void *windowA, const void *windowB) { - return strcmp((*((WindowInfo**)windowA))->filename, - (*((WindowInfo**)windowB))->filename); + return strcmp((*((WindowInfo**)windowA))->editorInfo->filename, + (*((WindowInfo**)windowB))->editorInfo->filename); } /* @@ -1841,7 +1841,7 @@ nWritable = 0; continue; } - if (!IS_ANY_LOCKED(w->lockReasons)) ++nWritable; + if (!IS_ANY_LOCKED(w->editorInfo->lockReasons)) ++nWritable; } return nWritable; } @@ -1862,7 +1862,7 @@ /* Make a sorted list of writable windows */ windows = (WindowInfo **)XtMalloc(sizeof(WindowInfo *) * nWritable); for (w=WindowList, i=0; w!=NULL; w=w->next) - if (!IS_ANY_LOCKED(w->lockReasons)) windows[i++] = w; + if (!IS_ANY_LOCKED(w->editorInfo->lockReasons)) windows[i++] = w; qsort(windows, nWritable, sizeof(WindowInfo *), compareWindowNames); window->writableWindows = windows; @@ -1933,7 +1933,7 @@ file status has changed or the file was locked in the mean time (possible due to Lesstif modal dialog bug), we just skip the window. */ - if (!IS_ANY_LOCKED(writableWin->lockReasons)) { + if (!IS_ANY_LOCKED(writableWin->editorInfo->lockReasons)) { noWritableLeft = False; writableWin->multiFileReplSelected = True; writableWin->multiFileBusy = True; /* Avoid multi-beep/dialog */ @@ -2061,10 +2061,10 @@ for (i = 0; i < nWritable; ++i) { w = window->writableWindows[i]; - if (usePathNames && window->filenameSet) { - sprintf(buf, "%s%s", w->path, w->filename); + if (usePathNames && window->editorInfo->filenameSet) { + sprintf(buf, "%s%s", w->editorInfo->path, w->editorInfo->filename); } else { - sprintf(buf, "%s", w->filename); + sprintf(buf, "%s", w->editorInfo->filename); } names[i] = XmStringCreateSimple(buf); } @@ -2806,7 +2806,7 @@ } /* select the text found string */ - BufSelect(window->buffer, startPos, endPos); + BufSelect(window->editorInfo->buffer, startPos, endPos); MakeSelectionVisible(window, window->lastFocus); TextSetCursorPos(window->lastFocus, endPos); @@ -2968,7 +2968,7 @@ int beepBeginPos = (direction == SEARCH_BACKWARD) ? beginPos-1:beginPos; iSearchTryBeepOnWrap(window, direction, beepBeginPos, beepBeginPos); iSearchRecordLastBeginPos(window, direction, window->iSearchStartPos); - BufUnselect(window->buffer); + BufUnselect(window->editorInfo->buffer); TextSetCursorPos(window->lastFocus, beginPos); return TRUE; } @@ -3005,7 +3005,7 @@ window->iSearchLastBeginPos = startPos; /* select the text found string */ - BufSelect(window->buffer, startPos, endPos); + BufSelect(window->editorInfo->buffer, startPos, endPos); MakeSelectionVisible(window, window->lastFocus); TextSetCursorPos(window->lastFocus, endPos); @@ -3318,26 +3318,26 @@ int constrain; /* if a marker is already drawn, erase it and cancel the timeout */ - if (window->flashTimeoutID != 0) { + if (window->editorInfo->flashTimeoutID != 0) { eraseFlash(window); - XtRemoveTimeOut(window->flashTimeoutID); - window->flashTimeoutID = 0; + XtRemoveTimeOut(window->editorInfo->flashTimeoutID); + window->editorInfo->flashTimeoutID = 0; } /* no flashing required */ - if (window->showMatchingStyle == NO_FLASH) { + if (window->editorInfo->showMatchingStyle == NO_FLASH) { return; } /* don't flash matching characters if there's a selection */ - if (window->buffer->primary.selected) + if (window->editorInfo->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); + c = BufGetCharacter(window->editorInfo->buffer, pos); style = GetHighlightInfo(window, pos); /* is the character one we want to flash? */ @@ -3351,7 +3351,7 @@ /* constrain the search to visible text only when in single-pane mode AND using delimiter flashing (otherwise search the whole buffer) */ constrain = ((window->nPanes == 0) && - (window->showMatchingStyle == FLASH_DELIMIT)); + (window->editorInfo->showMatchingStyle == FLASH_DELIMIT)); if (MatchingChars[matchIndex].direction == SEARCH_BACKWARD) { startPos = constrain ? TextFirstVisiblePos(textW) : 0; @@ -3360,7 +3360,7 @@ } else { startPos = pos; endPos = constrain ? TextLastVisiblePos(textW) : - window->buffer->length; + window->editorInfo->buffer->length; searchPos = startPos; } @@ -3369,37 +3369,37 @@ &matchPos)) return; - if (window->showMatchingStyle == FLASH_DELIMIT) { + if (window->editorInfo->showMatchingStyle == FLASH_DELIMIT) { /* Highlight either the matching character ... */ - BufHighlight(window->buffer, matchPos, matchPos+1); + BufHighlight(window->editorInfo->buffer, matchPos, matchPos+1); } else { /* ... or the whole range. */ if (MatchingChars[matchIndex].direction == SEARCH_BACKWARD) { - BufHighlight(window->buffer, matchPos, pos+1); + BufHighlight(window->editorInfo->buffer, matchPos, pos+1); } else { - BufHighlight(window->buffer, matchPos+1, pos); + BufHighlight(window->editorInfo->buffer, matchPos+1, pos); } } /* Set up a timer to erase the box after 1.5 seconds */ - window->flashTimeoutID = XtAppAddTimeOut( + window->editorInfo->flashTimeoutID = XtAppAddTimeOut( XtWidgetToApplicationContext(window->shell), 1500, flashTimeoutProc, window); - window->flashPos = matchPos; + window->editorInfo->flashPos = matchPos; } void SelectToMatchingCharacter(WindowInfo *window) { int selStart, selEnd; int startPos, endPos, matchPos; - textBuffer *buf = window->buffer; + textBuffer *buf = window->editorInfo->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); - if (window->overstrike) + if (window->editorInfo->overstrike) selEnd += 1; selStart = selEnd - 1; if (selStart < 0) { @@ -3437,14 +3437,14 @@ { int selStart, selEnd; int matchPos; - textBuffer *buf = window->buffer; + textBuffer *buf = window->editorInfo->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); - if (window->overstrike) + if (window->editorInfo->overstrike) selEnd += 1; selStart = selEnd - 1; if (selStart < 0) { @@ -3483,8 +3483,8 @@ int nestDepth, matchIndex, direction, beginPos, pos; char matchChar, c; void *style = NULL; - textBuffer *buf = window->buffer; - int matchSyntaxBased = window->matchSyntaxBased; + textBuffer *buf = window->editorInfo->buffer; + int matchSyntaxBased = window->editorInfo->matchSyntaxBased; /* If we don't match syntax based, fake a matching style. */ if (!matchSyntaxBased) style = styleToMatch; @@ -3548,7 +3548,7 @@ static void flashTimeoutProc(XtPointer clientData, XtIntervalId *id) { eraseFlash((WindowInfo *)clientData); - ((WindowInfo *)clientData)->flashTimeoutID = 0; + ((WindowInfo *)clientData)->editorInfo->flashTimeoutID = 0; } /* @@ -3557,7 +3557,7 @@ */ static void eraseFlash(WindowInfo *window) { - BufUnhighlight(window->buffer); + BufUnhighlight(window->editorInfo->buffer); } /* @@ -3615,18 +3615,18 @@ /* replace the text */ if (isRegexType(searchType)) { char replaceResult[SEARCHMAX+1], *foundString; - foundString = BufGetRange(window->buffer, searchExtentBW, + foundString = BufGetRange(window->editorInfo->buffer, searchExtentBW, searchExtentFW+1); replaceUsingRE(searchString, replaceString, foundString, startPos-searchExtentBW, replaceResult, SEARCHMAX, startPos == 0 ? '\0' : - BufGetCharacter(window->buffer, startPos-1), + BufGetCharacter(window->editorInfo->buffer, startPos-1), GetWindowDelimiters(window), defaultRegexFlags(searchType)); XtFree(foundString); - BufReplace(window->buffer, startPos, endPos, replaceResult); + BufReplace(window->editorInfo->buffer, startPos, endPos, replaceResult); replaceLen = strlen(replaceResult); } else { - BufReplace(window->buffer, startPos, endPos, replaceString); + BufReplace(window->editorInfo->buffer, startPos, endPos, replaceString); replaceLen = strlen(replaceString); } @@ -3683,24 +3683,24 @@ /* replace the text */ if (isRegexType(searchType)) { char replaceResult[SEARCHMAX], *foundString; - foundString = BufGetRange(window->buffer, searchExtentBW, searchExtentFW+1); + foundString = BufGetRange(window->editorInfo->buffer, searchExtentBW, searchExtentFW+1); replaceUsingRE(searchString, replaceString, foundString, startPos - searchExtentBW, replaceResult, SEARCHMAX, startPos == 0 ? '\0' : - BufGetCharacter(window->buffer, startPos-1), + BufGetCharacter(window->editorInfo->buffer, startPos-1), GetWindowDelimiters(window), defaultRegexFlags(searchType)); XtFree(foundString); - BufReplace(window->buffer, startPos, endPos, replaceResult); + BufReplace(window->editorInfo->buffer, startPos, endPos, replaceResult); replaceLen = strlen(replaceResult); } else { - BufReplace(window->buffer, startPos, endPos, replaceString); + 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->buffer); + BufUnselect(window->editorInfo->buffer); /* temporarily shut off autoShowInsertPos before setting the cursor position so MakeSelectionVisible gets a chance to place the replaced @@ -3794,17 +3794,17 @@ saveSearchHistory(searchString, replaceString, searchType, FALSE); /* find out where the selection is */ - if (!BufGetSelectionPos(window->buffer, &selStart, &selEnd, &isRect, + if (!BufGetSelectionPos(window->editorInfo->buffer, &selStart, &selEnd, &isRect, &rectStart, &rectEnd)) return; /* get the selected text */ if (isRect) { - selStart = BufStartOfLine(window->buffer, selStart); - selEnd = BufEndOfLine(window->buffer, selEnd); - fileString = BufGetRange(window->buffer, selStart, selEnd); + selStart = BufStartOfLine(window->editorInfo->buffer, selStart); + selEnd = BufEndOfLine(window->editorInfo->buffer, selEnd); + fileString = BufGetRange(window->editorInfo->buffer, selStart, selEnd); } else - fileString = BufGetSelectionText(window->buffer); + fileString = BufGetSelectionText(window->editorInfo->buffer); /* create a temporary buffer in which to do the replacements to hide the intermediate steps from the display routines, and so everything can @@ -3829,9 +3829,9 @@ /* if the selection is rectangular, verify that the found string is in the rectangle */ if (isRect) { - lineStart = BufStartOfLine(window->buffer, selStart+startPos); - if (BufCountDispChars(window->buffer, lineStart, selStart+startPos) < - rectStart || BufCountDispChars(window->buffer, lineStart, + lineStart = BufStartOfLine(window->editorInfo->buffer, selStart+startPos); + if (BufCountDispChars(window->editorInfo->buffer, lineStart, selStart+startPos) < + rectStart || BufCountDispChars(window->editorInfo->buffer, lineStart, selStart+endPos) > rectEnd) { if (fileString[endPos] == '\0') break; @@ -3840,9 +3840,9 @@ search after the end of the (false) match, because we could miss a valid match starting between the left boundary and the end of the false match. */ - if (BufCountDispChars(window->buffer, lineStart, + if (BufCountDispChars(window->editorInfo->buffer, lineStart, selStart+startPos) < rectStart && - BufCountDispChars(window->buffer, lineStart, + BufCountDispChars(window->editorInfo->buffer, lineStart, selStart+endPos) > rectStart) beginPos += 1; else @@ -3909,7 +3909,7 @@ user does not care and wants to have a faulty replacement. */ /* replace the selected range in the real buffer */ - BufReplace(window->buffer, selStart, selEnd, BufAsString(tempBuf)); + BufReplace(window->editorInfo->buffer, selStart, selEnd, BufAsString(tempBuf)); /* set the insert point at the end of the last replacement */ TextSetCursorPos(window->lastFocus, selStart + cursorPos + realOffset); @@ -3917,7 +3917,7 @@ /* leave non-rectangular selections selected (rect. ones after replacement are less useful since left/right positions are randomly adjusted) */ if (!isRect) { - BufSelect(window->buffer, selStart, selEnd + realOffset); + BufSelect(window->editorInfo->buffer, selStart, selEnd + realOffset); } } } else { @@ -3960,7 +3960,7 @@ saveSearchHistory(searchString, replaceString, searchType, FALSE); /* view the entire text buffer from the text area widget as a string */ - fileString = BufAsString(window->buffer); + fileString = BufAsString(window->editorInfo->buffer); newFileString = ReplaceAllInString(fileString, searchString, replaceString, searchType, ©Start, ©End, &replacementLen, @@ -3985,7 +3985,7 @@ } /* replace the contents of the text widget with the substituted text */ - BufReplace(window->buffer, copyStart, copyEnd, newFileString); + BufReplace(window->editorInfo->buffer, copyStart, copyEnd, newFileString); /* Move the cursor to the end of the last replacement */ TextSetCursorPos(window->lastFocus, copyStart + replacementLen); @@ -4131,14 +4131,14 @@ int *endPos, int *extentBW, int *extentFW) { const char *fileString; - int found, resp, fileEnd = window->buffer->length - 1, outsideBounds; + int found, resp, fileEnd = window->editorInfo->buffer->length - 1, outsideBounds; /* reject empty string */ if (*searchString == '\0') return FALSE; /* get the entire text buffer from the text area widget */ - fileString = BufAsString(window->buffer); + fileString = BufAsString(window->editorInfo->buffer); /* If we're already outside the boundaries, we must consider wrapping immediately (Note: fileEnd+1 is a valid starting position. Consider @@ -4653,7 +4653,7 @@ int found, isRect, rectStart, rectEnd, lineStart = 0; /* find length of selection, give up on no selection or too long */ - if (!BufGetEmptySelectionPos(window->buffer, &selStart, &selEnd, &isRect, + if (!BufGetEmptySelectionPos(window->editorInfo->buffer, &selStart, &selEnd, &isRect, &rectStart, &rectEnd)) return FALSE; if (selEnd - selStart > SEARCHMAX) @@ -4661,8 +4661,8 @@ /* if the selection is rectangular, don't match if it spans lines */ if (isRect) { - lineStart = BufStartOfLine(window->buffer, selStart); - if (lineStart != BufStartOfLine(window->buffer, selEnd)) + lineStart = BufStartOfLine(window->editorInfo->buffer, selStart); + if (lineStart != BufStartOfLine(window->editorInfo->buffer, selEnd)) return FALSE; } @@ -4671,14 +4671,14 @@ if (isRect) { int stringStart = lineStart + rectStart - regexLookContext; if (stringStart < 0) stringStart = 0; - string = BufGetRange(window->buffer, stringStart, + string = BufGetRange(window->editorInfo->buffer, stringStart, lineStart + rectEnd + regexLookContext); selLen = rectEnd - rectStart; beginPos = lineStart + rectStart - stringStart; } else { int stringStart = selStart - regexLookContext; if (stringStart < 0) stringStart = 0; - string = BufGetRange(window->buffer, stringStart, + string = BufGetRange(window->editorInfo->buffer, stringStart, selEnd + regexLookContext); selLen = selEnd - selStart; beginPos = selStart - stringStart; @@ -4704,7 +4704,7 @@ /* return the start and end of the selection */ if (isRect) - GetSimpleSelection(window->buffer, left, right); + GetSimpleSelection(window->editorInfo->buffer, left, right); else { *left = selStart; *right = selEnd; diff -ur nedit_official/source/selection.c nedit_mod/source/selection.c --- nedit_official/source/selection.c 2008-02-26 23:21:47.000000000 +0100 +++ nedit_mod/source/selection.c 2008-03-17 23:50:02.000000000 +0100 @@ -167,9 +167,9 @@ /* 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); + if (window->editorInfo->buffer->primary.selected) { + selText = BufGetSelectionText(window->editorInfo->buffer); + BufUnsubstituteNullChars(selText, window->editorInfo->buffer); return selText; } @@ -298,7 +298,7 @@ if ((strchr(nameText, ':') == NULL) && (strlen(nameText) > 1) && !((nameText[0] == '[') && (nameText[1] != '-') && (nameText[1] != '.'))) { - strcpy(filename, window->path); + strcpy(filename, window->editorInfo->path); strcat(filename, nameText); strcpy(nameText, filename); } @@ -308,7 +308,7 @@ /* If path name is relative, make it refer to current window's directory */ if (nameText[0] != '/') { - strcpy(filename, window->path); + strcpy(filename, window->editorInfo->path); strcat(filename, nameText); strcpy(nameText, filename); } @@ -396,25 +396,25 @@ if (lineNum < 1) lineNum = 1; lineEnd = -1; - for (i=1; i<=lineNum && lineEndbuffer->length; i++) { + for (i=1; i<=lineNum && lineEndeditorInfo->buffer->length; i++) { lineStart = lineEnd + 1; - lineEnd = BufEndOfLine(window->buffer, lineStart); + lineEnd = BufEndOfLine(window->editorInfo->buffer, lineStart); } /* highlight the line */ if (i>lineNum) { /* Line was found */ - if (lineEnd < window->buffer->length) { - BufSelect(window->buffer, lineStart, lineEnd+1); + if (lineEnd < window->editorInfo->buffer->length) { + BufSelect(window->editorInfo->buffer, lineStart, lineEnd+1); } else { /* Don't select past the end of the buffer ! */ - BufSelect(window->buffer, lineStart, window->buffer->length); + BufSelect(window->editorInfo->buffer, lineStart, window->editorInfo->buffer->length); } } else { /* Line was not found -> position the selection & cursor at the end without making a real selection and beep */ - lineStart = window->buffer->length; - BufSelect(window->buffer, lineStart, lineStart); + lineStart = window->editorInfo->buffer->length; + BufSelect(window->editorInfo->buffer, lineStart, lineStart); XBell(TheDisplay, 0); } MakeSelectionVisible(window, window->lastFocus); @@ -577,7 +577,7 @@ /* store the cursor location and selection position in the table */ window->markTable[index].label = label; - memcpy(&window->markTable[index].sel, &window->buffer->primary, + memcpy(&window->markTable[index].sel, &window->editorInfo->buffer->primary, sizeof(selection)); window->markTable[index].cursorPos = TextGetCursorPos(widget); } @@ -600,24 +600,24 @@ /* reselect marked the selection, and move the cursor to the marked pos */ sel = &window->markTable[index].sel; - oldSel = &window->buffer->primary; + oldSel = &window->editorInfo->buffer->primary; cursorPos = window->markTable[index].cursorPos; if (extendSel) { oldStart = oldSel->selected ? oldSel->start : TextGetCursorPos(w); oldEnd = oldSel->selected ? oldSel->end : TextGetCursorPos(w); newStart = sel->selected ? sel->start : cursorPos; newEnd = sel->selected ? sel->end : cursorPos; - BufSelect(window->buffer, oldStart < newStart ? oldStart : newStart, + BufSelect(window->editorInfo->buffer, oldStart < newStart ? oldStart : newStart, oldEnd > newEnd ? oldEnd : newEnd); } else { if (sel->selected) { if (sel->rectangular) - BufRectSelect(window->buffer, sel->start, sel->end, + BufRectSelect(window->editorInfo->buffer, sel->start, sel->end, sel->rectStart, sel->rectEnd); else - BufSelect(window->buffer, sel->start, sel->end); + BufSelect(window->editorInfo->buffer, sel->start, sel->end); } else - BufUnselect(window->buffer); + BufUnselect(window->editorInfo->buffer); } /* Move the window into a pleasing position relative to the selection diff -ur nedit_official/source/server.c nedit_mod/source/server.c --- nedit_official/source/server.c 2007-12-31 12:12:43.000000000 +0100 +++ nedit_mod/source/server.c 2008-03-17 23:50:02.000000000 +0100 @@ -231,8 +231,8 @@ */ static void deleteFileOpenProperty(WindowInfo *window) { - if (window->filenameSet) { - Atom atom = findFileOpenProperty(window->filename, window->path); + if (window->editorInfo->filenameSet) { + Atom atom = findFileOpenProperty(window->editorInfo->filename, window->editorInfo->path); deleteProperty(&atom); } } @@ -266,9 +266,9 @@ /* Get hold of the property to use when closing the file. */ static void getFileClosedProperty(WindowInfo *window) { - if (window->filenameSet) { - window->fileClosedAtom = findFileClosedProperty(window->filename, - window->path); + if (window->editorInfo->filenameSet) { + window->editorInfo->fileClosedAtom = findFileClosedProperty(window->editorInfo->filename, + window->editorInfo->path); } } @@ -277,8 +277,8 @@ */ void DeleteFileClosedProperty(WindowInfo *window) { - if (window->filenameSet) { - deleteProperty(&window->fileClosedAtom); + if (window->editorInfo->filenameSet) { + deleteProperty(&window->editorInfo->fileClosedAtom); } } @@ -311,7 +311,7 @@ /* A new window is requested, unless we find an untitled unmodified document on the current desktop */ for (window=WindowList; window!=NULL; window=window->next) { - if (window->filenameSet || window->fileChanged || + if (window->editorInfo->filenameSet || window->editorInfo->fileChanged || window->macroCmdData != NULL) { continue; } @@ -351,7 +351,7 @@ (or just pop one up if it already exists) */ if (string[0] == '\0') { for (window=WindowList; window!=NULL; window=window->next) - if (!window->filenameSet && !window->fileChanged && + if (!window->editorInfo->filenameSet && !window->editorInfo->fileChanged && isLocatedOnDesktop(window, currentDesktop)) break; if (window == NULL) { @@ -413,7 +413,7 @@ */ if (fileLen <= 0) { for (window=WindowList; window!=NULL; window=window->next) - if (!window->filenameSet && !window->fileChanged && + if (!window->editorInfo->filenameSet && !window->editorInfo->fileChanged && isLocatedOnDesktop(window, currentDesktop)) break; diff -ur nedit_official/source/shell.c nedit_mod/source/shell.c --- nedit_official/source/shell.c 2008-01-04 23:11:04.000000000 +0100 +++ nedit_mod/source/shell.c 2008-03-17 23:50:02.000000000 +0100 @@ -168,16 +168,16 @@ /* Get the selection and the range in character positions that it occupies. Beep and return if no selection */ - text = BufGetSelectionText(window->buffer); + text = BufGetSelectionText(window->editorInfo->buffer); if (*text == '\0') { XtFree(text); XBell(TheDisplay, 0); return; } textLen = strlen(text); - BufUnsubstituteNullChars(text, window->buffer); - left = window->buffer->primary.start; - right = window->buffer->primary.end; + 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, command, text, textLen, ACCUMULATE | ERROR_DIALOGS | @@ -204,15 +204,15 @@ /* get the selection or the insert position */ pos = TextGetCursorPos(window->lastFocus); - if (GetSimpleSelection(window->buffer, &left, &right)) + if (GetSimpleSelection(window->editorInfo->buffer, &left, &right)) flags = ACCUMULATE | REPLACE_SELECTION; else left = right = pos; /* Substitute the current file name for % and the current line number for # in the shell command */ - strcpy(fullName, window->path); - strcat(fullName, window->filename); + strcpy(fullName, window->editorInfo->path); + strcat(fullName, window->editorInfo->filename); TextPosToLineAndCol(window->lastFocus, pos, &line, &column); sprintf(lineNumber, "%d", line); @@ -270,23 +270,23 @@ /* get all of the text on the line with the insert position */ pos = TextGetCursorPos(window->lastFocus); - if (!GetSimpleSelection(window->buffer, &left, &right)) { + if (!GetSimpleSelection(window->editorInfo->buffer, &left, &right)) { left = right = pos; - left = BufStartOfLine(window->buffer, left); - right = BufEndOfLine(window->buffer, right); + left = BufStartOfLine(window->editorInfo->buffer, left); + right = BufEndOfLine(window->editorInfo->buffer, right); insertPos = right; } else - insertPos = BufEndOfLine(window->buffer, right); - cmdText = BufGetRange(window->buffer, left, right); - BufUnsubstituteNullChars(cmdText, window->buffer); + 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->buffer, insertPos, "\n"); + BufInsert(window->editorInfo->buffer, insertPos, "\n"); /* Substitute the current file name for % and the current line number for # in the shell command */ - strcpy(fullName, window->path); - strcat(fullName, window->filename); + strcpy(fullName, window->editorInfo->path); + strcat(fullName, window->editorInfo->filename); TextPosToLineAndCol(window->lastFocus, pos, &line, &column); sprintf(lineNumber, "%d", line); @@ -333,8 +333,8 @@ /* Substitute the current file name for % and the current line number for # in the shell command */ - strcpy(fullName, window->path); - strcat(fullName, window->filename); + strcpy(fullName, window->editorInfo->path); + strcat(fullName, window->editorInfo->filename); pos = TextGetCursorPos(window->lastFocus); TextPosToLineAndCol(window->lastFocus, pos, &line, &column); sprintf(lineNumber, "%d", line); @@ -352,7 +352,7 @@ /* Get the command input as a text string. If there is input, errors shouldn't be mixed in with output, so set flags to ERROR_DIALOGS */ if (input == FROM_SELECTION) { - text = BufGetSelectionText(window->buffer); + text = BufGetSelectionText(window->editorInfo->buffer); if (*text == '\0') { XtFree(text); free(subsCommand); @@ -361,13 +361,13 @@ } flags |= ACCUMULATE | ERROR_DIALOGS; } else if (input == FROM_WINDOW) { - text = BufGetAll(window->buffer); + text = BufGetAll(window->editorInfo->buffer); flags |= ACCUMULATE | ERROR_DIALOGS; } else if (input == FROM_EITHER) { - text = BufGetSelectionText(window->buffer); + text = BufGetSelectionText(window->editorInfo->buffer); if (*text == '\0') { XtFree(text); - text = BufGetAll(window->buffer); + text = BufGetAll(window->editorInfo->buffer); } flags |= ACCUMULATE | ERROR_DIALOGS; } else /* FROM_NONE */ @@ -377,7 +377,7 @@ put the nuls back in before exporting the text */ if (text != NULL) { textLen = strlen(text); - BufUnsubstituteNullChars(text, window->buffer); + BufUnsubstituteNullChars(text, window->editorInfo->buffer); } else textLen = 0; @@ -389,7 +389,7 @@ flags |= OUTPUT_TO_DIALOG; left = right = 0; } else if (output == TO_NEW_WINDOW) { - EditNewFile(GetPrefOpenInTab()?inWindow:NULL, NULL, False, NULL, window->path); + EditNewFile(GetPrefOpenInTab()?inWindow:NULL, NULL, False, NULL, window->editorInfo->path); outWidget = WindowList->textArea; inWindow = WindowList; left = right = 0; @@ -399,20 +399,20 @@ if (outputReplacesInput && input != FROM_NONE) { if (input == FROM_WINDOW) { left = 0; - right = window->buffer->length; + right = window->editorInfo->buffer->length; } else if (input == FROM_SELECTION) { - GetSimpleSelection(window->buffer, &left, &right); + GetSimpleSelection(window->editorInfo->buffer, &left, &right); flags |= ACCUMULATE | REPLACE_SELECTION; } else if (input == FROM_EITHER) { - if (GetSimpleSelection(window->buffer, &left, &right)) + if (GetSimpleSelection(window->editorInfo->buffer, &left, &right)) flags |= ACCUMULATE | REPLACE_SELECTION; else { left = 0; - right = window->buffer->length; + right = window->editorInfo->buffer->length; } } } else { - if (GetSimpleSelection(window->buffer, &left, &right)) + if (GetSimpleSelection(window->editorInfo->buffer, &left, &right)) flags |= ACCUMULATE | REPLACE_SELECTION; else left = right = TextGetCursorPos(window->lastFocus); @@ -505,7 +505,7 @@ SetSensitive(window, window->cancelShellItem, True); /* fork the subprocess and issue the command */ - childPid = forkCommand(window->shell, command, window->path, &stdinFD, + childPid = forkCommand(window->shell, command, window->editorInfo->path, &stdinFD, &stdoutFD, (flags & ERROR_DIALOGS) ? &stderrFD : NULL); /* set the pipes connected to the process for non-blocking i/o */ diff -ur nedit_official/source/shift.c nedit_mod/source/shift.c --- nedit_official/source/shift.c 2006-10-17 12:10:59.000000000 +0200 +++ nedit_mod/source/shift.c 2008-03-17 23:50:02.000000000 +0100 @@ -84,7 +84,7 @@ int selStart, selEnd, isRect, rectStart, rectEnd; int shiftedLen, newEndPos, cursorPos, origLength, emTabDist, shiftDist; char *text, *shiftedText; - textBuffer *buf = window->buffer; + textBuffer *buf = window->editorInfo->buffer; /* get selection, if no text selected, use current insert position */ if (!BufGetSelectionPos(buf, &selStart, &selEnd, &isRect, @@ -136,7 +136,7 @@ int selStart, int selEnd, int rectStart, int rectEnd) { int offset, emTabDist; - textBuffer *tempBuf, *buf = window->buffer; + textBuffer *tempBuf, *buf = window->editorInfo->buffer; char *text; /* Make sure selStart and SelEnd refer to whole lines */ @@ -192,7 +192,7 @@ */ static void changeCase(WindowInfo *window, int makeUpper) { - textBuffer *buf = window->buffer; + textBuffer *buf = window->editorInfo->buffer; char *text, *c; char oldChar; int cursorPos, start, end, isRect, rectStart, rectEnd; @@ -236,12 +236,12 @@ void FillSelection(WindowInfo *window) { - textBuffer *buf = window->buffer; + textBuffer *buf = window->editorInfo->buffer; char *text, *filledText; int left, right, nCols, len, isRect, rectStart, rectEnd; int rightMargin, wrapMargin; int insertPos = TextGetCursorPos(window->lastFocus); - int hasSelection = window->buffer->primary.selected; + int hasSelection = window->editorInfo->buffer->primary.selected; /* Find the range of characters and get the text to fill. If there is a selection, use it but extend non-rectangular selections to encompass diff -ur nedit_official/source/smartIndent.c nedit_mod/source/smartIndent.c --- nedit_official/source/smartIndent.c 2006-12-02 11:27:06.000000000 +0100 +++ nedit_mod/source/smartIndent.c 2008-03-17 23:50:02.000000000 +0100 @@ -764,13 +764,13 @@ return; } } - window->smartIndentData = (void *)winData; + window->editorInfo->smartIndentData = (void *)winData; } void EndSmartIndent(WindowInfo *window) { windowSmartIndentData *winData = - (windowSmartIndentData *)window->smartIndentData; + (windowSmartIndentData *)window->editorInfo->smartIndentData; if (winData == NULL) return; @@ -780,7 +780,7 @@ FreeProgram(winData->modMacro); FreeProgram(winData->newlineMacro); XtFree((char *)winData); - window->smartIndentData = NULL; + window->editorInfo->smartIndentData = NULL; } /* @@ -802,7 +802,7 @@ WindowInfo *window = WidgetToWindow(w); smartIndentCBStruct *cbInfo = (smartIndentCBStruct *)callData; - if (window->smartIndentData == NULL) + if (window->editorInfo->smartIndentData == NULL) return; if (cbInfo->reason == CHAR_TYPED) executeModMacro(window, cbInfo); @@ -817,7 +817,7 @@ static void executeNewlineMacro(WindowInfo *window, smartIndentCBStruct *cbInfo) { windowSmartIndentData *winData = - (windowSmartIndentData *)window->smartIndentData; + (windowSmartIndentData *)window->editorInfo->smartIndentData; /* posValue probably shouldn't be static due to re-entrance issues */ static DataValue posValue = {INT_TAG, {0}}; DataValue result; @@ -876,7 +876,7 @@ Boolean InSmartIndentMacros(WindowInfo *window) { windowSmartIndentData *winData = - (windowSmartIndentData *)window->smartIndentData; + (windowSmartIndentData *)window->editorInfo->smartIndentData; return((winData && (winData->inModMacro || winData->inNewLineMacro))); } @@ -888,7 +888,7 @@ static void executeModMacro(WindowInfo *window,smartIndentCBStruct *cbInfo) { windowSmartIndentData *winData = - (windowSmartIndentData *)window->smartIndentData; + (windowSmartIndentData *)window->editorInfo->smartIndentData; /* args probably shouldn't be static due to future re-entrance issues */ static DataValue args[2] = {{INT_TAG, {0}}, {STRING_TAG, {0}}}; /* after 5.2 release remove inModCB and use new winData->inModMacro value */ @@ -1713,7 +1713,7 @@ re-initialize the smart indent macros (in case they have initialization data which depends on common data) */ for (window=WindowList; window!=NULL; window=window->next) { - if (window->indentStyle == SMART_INDENT && + if (window->editorInfo->indentStyle == SMART_INDENT && window->languageMode != PLAIN_LANGUAGE_MODE) { EndSmartIndent(window); BeginSmartIndent(window, False); @@ -1783,7 +1783,7 @@ lmName = LanguageModeName(window->languageMode); if (lmName != NULL && !strcmp(lmName, newMacros->lmName)) { SetSensitive(window, window->smartIndentItem, True); - if (window->indentStyle == SMART_INDENT && + if (window->editorInfo->indentStyle == SMART_INDENT && window->languageMode != PLAIN_LANGUAGE_MODE) { EndSmartIndent(window); BeginSmartIndent(window, False); diff -ur nedit_official/source/tags.c nedit_mod/source/tags.c --- nedit_official/source/tags.c 2008-03-01 23:18:06.000000000 +0100 +++ nedit_mod/source/tags.c 2008-03-17 23:50:02.000000000 +0100 @@ -1023,7 +1023,7 @@ if (in_buffer == NULL) { /* get the entire (sigh) text buffer from the text area widget */ - fileString = BufAsString(window->buffer); + fileString = BufAsString(window->editorInfo->buffer); } else { fileString = in_buffer; } @@ -1039,7 +1039,7 @@ ctagsMode=1; } else if (searchString[0] == '?') { dir = SEARCH_BACKWARD; - /* searchStartPos = window->buffer->length; */ + /* searchStartPos = window->editorInfo->buffer->length; */ searchStartPos = strlen(fileString); ctagsMode=1; } else { @@ -1149,8 +1149,8 @@ tagPosInf[nMatches]=startPos; ParseFilename(tagFiles[nMatches], filename, pathname); /* Is this match in the current file? If so, use it! */ - if (GetPrefSmartTags() && !strcmp(window->filename,filename) - && !strcmp(window->path,pathname) ) { + if (GetPrefSmartTags() && !strcmp(window->editorInfo->filename,filename) + && !strcmp(window->editorInfo->path,pathname) ) { if (nMatches) { strcpy(tagFiles[0],tagFiles[nMatches]); strcpy(tagSearch[0],tagSearch[nMatches]); @@ -1160,7 +1160,7 @@ break; } /* Is this match in the same dir. as the current file? */ - if (!strcmp(window->path,pathname)) { + if (!strcmp(window->editorInfo->path,pathname)) { samePath++; pathMatch=nMatches; } @@ -1474,12 +1474,12 @@ } /* select the matched string */ - BufSelect(windowToSearch->buffer, startPos, endPos); + BufSelect(windowToSearch->editorInfo->buffer, startPos, endPos); RaiseFocusDocumentWindow(windowToSearch, True); /* Position it nicely in the window, about 1/4 of the way down from the top */ - lineNum = BufCountLines(windowToSearch->buffer, 0, startPos); + lineNum = BufCountLines(windowToSearch->editorInfo->buffer, 0, startPos); XtVaGetValues(windowToSearch->lastFocus, textNrows, &rows, NULL); TextSetScroll(windowToSearch->lastFocus, lineNum - rows/4, 0); TextSetCursorPos(windowToSearch->lastFocus, endPos); diff -ur nedit_official/source/text.c nedit_mod/source/text.c --- nedit_official/source/text.c 2008-01-04 23:11:04.000000000 +0100 +++ nedit_mod/source/text.c 2008-03-17 23:50:02.000000000 +0100 @@ -2255,7 +2255,7 @@ TakeMotifDestination(w, e->time); chars[nChars] = '\0'; - if (!BufSubstituteNullChars(chars, nChars, window->buffer)) { + if (!BufSubstituteNullChars(chars, nChars, window->editorInfo->buffer)) { DialogF(DF_ERR, window->shell, 1, "Error", "Too much binary data", "OK"); return; } diff -ur nedit_official/source/undo.c nedit_mod/source/undo.c --- nedit_official/source/undo.c 2008-01-04 23:11:05.000000000 +0100 +++ nedit_mod/source/undo.c 2008-03-17 23:50:02.000000000 +0100 @@ -73,7 +73,7 @@ void Undo(WindowInfo *window) { - UndoInfo *undo = window->undo; + UndoInfo *undo = window->editorInfo->undo; int restoredTextLength; /* return if nothing to undo */ @@ -88,11 +88,11 @@ undo->inUndo = True; /* use the saved undo information to reverse changes */ - BufReplace(window->buffer, undo->startPos, undo->endPos, + BufReplace(window->editorInfo->buffer, undo->startPos, undo->endPos, (undo->oldText != NULL ? undo->oldText : "")); restoredTextLength = undo->oldText != NULL ? strlen(undo->oldText) : 0; - if (!window->buffer->primary.selected || GetPrefUndoModifiesSelection()) { + if (!window->editorInfo->buffer->primary.selected || GetPrefUndoModifiesSelection()) { /* position the cursor in the focus pane after the changed text to show the user where the undo was done */ TextSetCursorPos(window->lastFocus, undo->startPos + @@ -101,11 +101,11 @@ if (GetPrefUndoModifiesSelection()) { if (restoredTextLength > 0) { - BufSelect(window->buffer, undo->startPos, undo->startPos + + BufSelect(window->editorInfo->buffer, undo->startPos, undo->startPos + restoredTextLength); } else { - BufUnselect(window->buffer); + BufUnselect(window->editorInfo->buffer); } } MakeSelectionVisible(window, window->lastFocus); @@ -125,11 +125,11 @@ void Redo(WindowInfo *window) { - UndoInfo *redo = window->redo; + UndoInfo *redo = window->editorInfo->redo; int restoredTextLength; /* return if nothing to redo */ - if (window->redo == NULL) + if (window->editorInfo->redo == NULL) return; /* BufReplace will eventually call SaveUndoInformation. To indicate @@ -138,11 +138,11 @@ redo->inUndo = True; /* use the saved redo information to reverse changes */ - BufReplace(window->buffer, redo->startPos, redo->endPos, + BufReplace(window->editorInfo->buffer, redo->startPos, redo->endPos, (redo->oldText != NULL ? redo->oldText : "")); restoredTextLength = redo->oldText != NULL ? strlen(redo->oldText) : 0; - if (!window->buffer->primary.selected || GetPrefUndoModifiesSelection()) { + if (!window->editorInfo->buffer->primary.selected || GetPrefUndoModifiesSelection()) { /* position the cursor in the focus pane after the changed text to show the user where the undo was done */ TextSetCursorPos(window->lastFocus, redo->startPos + @@ -151,11 +151,11 @@ if (GetPrefUndoModifiesSelection()) { if (restoredTextLength > 0) { - BufSelect(window->buffer, redo->startPos, redo->startPos + + BufSelect(window->editorInfo->buffer, redo->startPos, redo->startPos + restoredTextLength); } else { - BufUnselect(window->buffer); + BufUnselect(window->editorInfo->buffer); } } MakeSelectionVisible(window, window->lastFocus); @@ -186,14 +186,14 @@ int nDeleted, const char *deletedText) { int newType, oldType; - UndoInfo *u, *undo = window->undo; + UndoInfo *u, *undo = window->editorInfo->undo; int isUndo = (undo != NULL && undo->inUndo); - int isRedo = (window->redo != NULL && window->redo->inUndo); + int isRedo = (window->editorInfo->redo != NULL && window->editorInfo->redo->inUndo); /* redo operations become invalid once the user begins typing or does other editing. If this is not a redo or undo operation and a redo list still exists, clear it and dim the redo menu item */ - if (!(isUndo || isRedo) && window->redo != NULL) + if (!(isUndo || isRedo) && window->editorInfo->redo != NULL) ClearRedoList(window); /* figure out what kind of editing operation this is, and recall @@ -210,13 +210,13 @@ ** is currently in an unmodified state, don't accumulate operations ** across the save, so the user can undo back to the unmodified state. */ - if (window->fileChanged) { + if (window->editorInfo->fileChanged) { /* normal sequential character insertion */ if ( ((oldType == ONE_CHAR_INSERT || oldType == ONE_CHAR_REPLACE) && newType == ONE_CHAR_INSERT) && (pos == undo->endPos)) { undo->endPos++; - window->autoSaveCharCount++; + window->editorInfo->autoSaveCharCount++; return; } @@ -225,7 +225,7 @@ (pos == undo->endPos)) { appendDeletedText(window, deletedText, nDeleted, FORWARD); undo->endPos++; - window->autoSaveCharCount++; + window->editorInfo->autoSaveCharCount++; return; } @@ -267,15 +267,15 @@ } /* increment the operation count for the autosave feature */ - window->autoSaveOpCount++; + window->editorInfo->autoSaveOpCount++; /* if the window is currently unmodified, remove the previous restoresToSaved marker, and set it on this record */ - if (!window->fileChanged) { + if (!window->editorInfo->fileChanged) { undo->restoresToSaved = True; - for (u=window->undo; u!=NULL; u=u->next) + for (u=window->editorInfo->undo; u!=NULL; u=u->next) u->restoresToSaved = False; - for (u=window->redo; u!=NULL; u=u->next) + for (u=window->editorInfo->redo; u!=NULL; u=u->next) u->restoresToSaved = False; } @@ -296,12 +296,12 @@ */ void ClearUndoList(WindowInfo *window) { - while (window->undo != NULL) + while (window->editorInfo->undo != NULL) removeUndoItem(window); } void ClearRedoList(WindowInfo *window) { - while (window->redo != NULL) + while (window->editorInfo->redo != NULL) removeRedoItem(window); } @@ -314,25 +314,27 @@ { /* Make the undo menu item sensitive now that there's something to undo */ - if (window->undo == NULL) { - SetSensitive(window, window->undoItem, True); + if (window->editorInfo->undo == NULL) { + WindowInfo *w; + for(w = window->editorInfo->master; w; w = w->nextSlave) + SetSensitive(w, w->undoItem, True); SetBGMenuUndoSensitivity(window, True); } /* Add the item to the beginning of the list */ - undo->next = window->undo; - window->undo = undo; + undo->next = window->editorInfo->undo; + window->editorInfo->undo = undo; /* Increment the operation and memory counts */ - window->undoOpCount++; - window->undoMemUsed += undo->oldLen; + window->editorInfo->undoOpCount++; + window->editorInfo->undoMemUsed += undo->oldLen; /* Trim the list if it exceeds any of the limits */ - if (window->undoOpCount > UNDO_OP_LIMIT) + if (window->editorInfo->undoOpCount > UNDO_OP_LIMIT) trimUndoList(window, UNDO_OP_TRIMTO); - if (window->undoMemUsed > UNDO_WORRY_LIMIT) + if (window->editorInfo->undoMemUsed > UNDO_WORRY_LIMIT) trimUndoList(window, UNDO_WORRY_TRIMTO); - if (window->undoMemUsed > UNDO_PURGE_LIMIT) + if (window->editorInfo->undoMemUsed > UNDO_PURGE_LIMIT) trimUndoList(window, UNDO_PURGE_TRIMTO); } @@ -342,14 +344,16 @@ static void addRedoItem(WindowInfo *window, UndoInfo *redo) { /* Make the redo menu item sensitive now that there's something to redo */ - if (window->redo == NULL) { - SetSensitive(window, window->redoItem, True); + if (window->editorInfo->redo == NULL) { + WindowInfo *w; + for(w = window->editorInfo->master; w; w = w->nextSlave) + SetSensitive(w, w->redoItem, True); SetBGMenuRedoSensitivity(window, True); } /* Add the item to the beginning of the list */ - redo->next = window->redo; - window->redo = redo; + redo->next = window->editorInfo->redo; + window->editorInfo->redo = redo; } /* @@ -357,22 +361,24 @@ */ static void removeUndoItem(WindowInfo *window) { - UndoInfo *undo = window->undo; + UndoInfo *undo = window->editorInfo->undo; if (undo == NULL) return; /* Decrement the operation and memory counts */ - window->undoOpCount--; - window->undoMemUsed -= undo->oldLen; + window->editorInfo->undoOpCount--; + window->editorInfo->undoMemUsed -= undo->oldLen; /* Remove and free the item */ - window->undo = undo->next; + window->editorInfo->undo = undo->next; freeUndoRecord(undo); /* if there are no more undo records left, dim the Undo menu item */ - if (window->undo == NULL) { - SetSensitive(window, window->undoItem, False); + if (window->editorInfo->undo == NULL) { + WindowInfo *w; + for(w = window->editorInfo->master; w; w = w->nextSlave) + SetSensitive(w, w->undoItem, False); SetBGMenuUndoSensitivity(window, False); } } @@ -382,15 +388,17 @@ */ static void removeRedoItem(WindowInfo *window) { - UndoInfo *redo = window->redo; + UndoInfo *redo = window->editorInfo->redo; /* Remove and free the item */ - window->redo = redo->next; + window->editorInfo->redo = redo->next; freeUndoRecord(redo); /* if there are no more redo records left, dim the Redo menu item */ - if (window->redo == NULL) { - SetSensitive(window, window->redoItem, False); + if (window->editorInfo->redo == NULL) { + WindowInfo *w; + for(w = window->editorInfo->master; w; w = w->nextSlave) + SetSensitive(w, w->redoItem, False); SetBGMenuRedoSensitivity(window, False); } } @@ -404,7 +412,7 @@ static void appendDeletedText(WindowInfo *window, const char *deletedText, int deletedLen, int direction) { - UndoInfo *undo = window->undo; + UndoInfo *undo = window->editorInfo->undo; char *comboText; /* re-allocate, adding space for the new character(s) */ @@ -420,7 +428,7 @@ } /* keep track of the additional memory now used by the undo list */ - window->undoMemUsed++; + window->editorInfo->undoMemUsed++; /* free the old saved text and attach the new */ XtFree(undo->oldText); @@ -437,11 +445,11 @@ int i; UndoInfo *u, *lastRec; - if (window->undo == NULL) + if (window->editorInfo->undo == NULL) return; /* Find last item on the list to leave intact */ - for (i=1, u=window->undo; inext); + for (i=1, u=window->editorInfo->undo; inext); if (u == NULL) return; @@ -450,8 +458,8 @@ while (lastRec->next != NULL) { u = lastRec->next; lastRec->next = u->next; - window->undoOpCount--; - window->undoMemUsed -= u->oldLen; + window->editorInfo->undoOpCount--; + window->editorInfo->undoMemUsed -= u->oldLen; freeUndoRecord(u); } } diff -ur nedit_official/source/userCmds.c nedit_mod/source/userCmds.c --- nedit_official/source/userCmds.c 2007-10-02 17:47:09.000000000 +0200 +++ nedit_mod/source/userCmds.c 2008-03-17 23:50:02.000000000 +0100 @@ -1417,7 +1417,7 @@ SetBGMenuRedoSensitivity(window, XtIsSensitive(window->redoItem)); } - DimSelectionDepUserMenuItems(window, window->buffer->primary.selected); + DimSelectionDepUserMenuItems(window, window->editorInfo->buffer->primary.selected); } /* diff -ur nedit_official/source/window.c nedit_mod/source/window.c --- nedit_official/source/window.c 2008-03-03 23:32:24.000000000 +0100 +++ nedit_mod/source/window.c 2008-03-17 23:50:03.000000000 +0100 @@ -148,6 +148,7 @@ extern void _XmDismissTearOff(Widget, XtPointer, XtPointer); static void hideTooltip(Widget tab); +static void shareBufferOnCloning(WindowInfo *window, WindowInfo *orgWin); static Pixmap createBitmapWithDepth(Widget w, char *data, unsigned int width, unsigned int height); static WindowInfo *getNextTabWindow(WindowInfo *window, int direction, @@ -167,6 +168,7 @@ static void showISearch(WindowInfo *window, int state); static void showStatsForm(WindowInfo *window); static void addToWindowList(WindowInfo *window); +static void addToCloneList(WindowInfo *window); static void removeFromWindowList(WindowInfo *window); static void focusCB(Widget w, WindowInfo *window, XtPointer callData); static void modifiedCB(int pos, int nInserted, int nDeleted, int nRestyled, @@ -186,7 +188,7 @@ static void patchedRemoveChild(Widget child); #endif static void refreshMenuBar(WindowInfo *window); -static void cloneDocument(WindowInfo *window, WindowInfo *orgWin); +static void mirrorDocumentStates(WindowInfo *window, WindowInfo *orgWin); static void cloneTextPanes(WindowInfo *window, WindowInfo *orgWin); static UndoInfo *cloneUndoItems(UndoInfo *orgList); static Widget containingPane(Widget w); @@ -205,7 +207,8 @@ /* ** Create a new editor window */ -WindowInfo *CreateWindow(const char *name, char *geometry, int iconic) +WindowInfo *CreateWindow(const char *name, char *geometry, int iconic, + EditorInfo *editorInfo) { Widget winShell, mainWin, menuBar, pane, text, stats, statsAreaForm; Widget closeTabBtn, tabForm, form; @@ -232,6 +235,45 @@ memset(window, 0, sizeof(WindowInfo)); be added here ? */ + if(editorInfo) { + /* share editorInfo among clones */ + window->editorInfo = editorInfo; + } + else { + window->editorInfo = (EditorInfo *)XtMalloc(sizeof(EditorInfo)); + window->editorInfo->master = window; + window->editorInfo->fileChanged = FALSE; + window->editorInfo->filenameSet = FALSE; + strcpy(window->editorInfo->filename, name); + 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->indentStyle = GetPrefAutoIndent(PLAIN_LANGUAGE_MODE); + window->editorInfo->autoSave = GetPrefAutoSave(); + window->editorInfo->saveOldVersion = GetPrefSaveOldVersion(); + window->editorInfo->wrapMode = GetPrefWrap(PLAIN_LANGUAGE_MODE); + window->editorInfo->overstrike = False; + window->editorInfo->ignoreModify = FALSE; + window->editorInfo->flashTimeoutID = 0; + CLEAR_ALL_LOCKS(window->editorInfo->lockReasons); + window->editorInfo->smartIndentData = NULL; + window->editorInfo->fileClosedAtom = None; + window->editorInfo->fileMode = 0; + window->editorInfo->fileUid = 0; + window->editorInfo->fileGid = 0; + window->editorInfo->fileFormat = UNIX_FILE_FORMAT; + window->editorInfo->lastModTime = 0; + window->editorInfo->fileMissing = True; + window->editorInfo->device = 0; + window->editorInfo->inode = 0; + window->editorInfo->showMatchingStyle = GetPrefShowMatching(); + window->editorInfo->matchSyntaxBased = GetPrefMatchSyntaxBased(); + } + + window->nextSlave = NULL; window->replaceDlog = NULL; window->replaceText = NULL; window->replaceWithText = NULL; @@ -250,30 +292,7 @@ window->multiFileBusy = FALSE; window->writableWindows = NULL; window->nWritableWindows = 0; - window->fileChanged = FALSE; - window->fileMode = 0; - window->fileUid = 0; - window->fileGid = 0; - window->filenameSet = FALSE; - window->fileFormat = UNIX_FILE_FORMAT; - window->lastModTime = 0; - window->fileMissing = True; - 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; - CLEAR_ALL_LOCKS(window->lockReasons); - window->indentStyle = GetPrefAutoIndent(PLAIN_LANGUAGE_MODE); - window->autoSave = GetPrefAutoSave(); - window->saveOldVersion = GetPrefSaveOldVersion(); - window->wrapMode = GetPrefWrap(PLAIN_LANGUAGE_MODE); - window->overstrike = False; - window->showMatchingStyle = GetPrefShowMatching(); - window->matchSyntaxBased = GetPrefMatchSyntaxBased(); window->showStats = GetPrefStatsLine(); window->showISearchLine = GetPrefISearchLine(); window->showLineNumbers = GetPrefLineNums(); @@ -289,10 +308,7 @@ } window->modeMessageDisplayed = FALSE; window->modeMessage = NULL; - window->ignoreModify = FALSE; window->windowMenuValid = FALSE; - window->flashTimeoutID = 0; - window->fileClosedAtom = None; window->wasSelected = FALSE; strcpy(window->fontName, GetPrefFontName()); @@ -310,7 +326,6 @@ window->highlightData = NULL; window->shellCmdData = NULL; window->macroCmdData = NULL; - window->smartIndentData = NULL; window->languageMode = PLAIN_LANGUAGE_MODE; window->iSearchHistIndex = 0; window->iSearchStartPos = -1; @@ -321,8 +336,6 @@ window->findLastRegexCase = TRUE; window->findLastLiteralCase = FALSE; window->tab = NULL; - window->device = 0; - window->inode = 0; /* If window geometry was specified, split it apart into a window position component and a window size component. Create a new geometry string @@ -745,22 +758,31 @@ with the text area widget. This is done so the syntax highlighting modify callback can be called to synchronize the style buffer BEFORE the text display's callback is called upon to display a modification */ - window->buffer = BufCreate(); - BufAddModifyCB(window->buffer, SyntaxHighlightModifyCB, window); + 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->buffer); - BufAddModifyCB(window->buffer, modifiedCB, window); + TextSetBuffer(text, window->editorInfo->buffer); + BufAddModifyCB(window->editorInfo->buffer, modifiedCB, window); /* Designate the permanent text area as the owner for selections */ - HandleXSelections(text); + if (!editorInfo) + 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(); - + if (!editorInfo) { + window->editorInfo->ignoreModify = True; + BufSetTabDistance(window->editorInfo->buffer, + GetPrefTabDist(PLAIN_LANGUAGE_MODE)); + window->editorInfo->ignoreModify = False; + window->editorInfo->buffer->useTabs = GetPrefInsertTabs(); + } + /* add the window to the global window list, update the Windows menus */ addToWindowList(window); + if (editorInfo) + addToCloneList(window); InvalidateWindowMenus(); showTabBar = GetShowTabBar(window); @@ -804,6 +826,45 @@ } /* +** create a clone in new window +*/ +WindowInfo *CreateCloneWindow(WindowInfo *window) +{ + WindowInfo *cloneWin; + Dimension windowHeight, windowWidth; + char *dim, geometry[MAX_GEOM_STRING_LEN]; + + /* create new window in roughly the size of original window, + to reduce flicker when the window is resized later */ + getGeometryString(window, geometry); + dim = strtok(geometry, "+-"); + cloneWin = CreateWindow(window->editorInfo->filename, dim, + False, window->editorInfo); + + /* duplicate the shell window setting. this, as well as the + statistic line and incr search line, must be done + before cloning window, else the height of split panes + may not come out correctly */ + XtVaGetValues(window->shell, XmNheight, &windowHeight, + XmNwidth, &windowWidth, NULL); + XtVaSetValues(cloneWin->shell, XmNheight, windowHeight, + XmNwidth, windowWidth, NULL); + + /* these settings should follow the detached buffer */ + ShowISearchLine(cloneWin, window->showISearchLine); + ShowStatsLine(cloneWin, window->showStats); + + /* clone the buffer & its pref settings */ + shareBufferOnCloning(cloneWin, window); + + /* this should keep the new buffer window fresh */ + RefreshWindowStates(cloneWin); + RefreshTabState(cloneWin); + + return cloneWin; +} + +/* ** ButtonPress event handler for tabs. */ static void tabClickEH(Widget w, XtPointer clientData, XEvent *event) @@ -878,10 +939,10 @@ const WindowInfo *a = *((WindowInfo**)windowA); const WindowInfo *b = *((WindowInfo**)windowB); - rc = strcmp(a->filename, b->filename); + rc = strcmp(a->editorInfo->filename, b->editorInfo->filename); if (rc != 0) return rc; - rc = strcmp(a->path, b->path); + rc = strcmp(a->editorInfo->path, b->editorInfo->path); return rc; } @@ -945,6 +1006,19 @@ return NULL; } +int NCloned(WindowInfo *window) +{ + WindowInfo *win; + int count = 0; + + for (win=WindowList; win; win=win->next) { + if (window->editorInfo->buffer == win->editorInfo->buffer) + count++; + } + + return count; +} + /* ** Close a document, or an editor window */ @@ -952,7 +1026,8 @@ { int keepWindow, state; char name[MAXPATHLEN]; - WindowInfo *win, *topBuf = NULL, *nextBuf = NULL; + EditorInfo *editorInfo = window->editorInfo; + WindowInfo *win, *nextSlave, *topBuf = NULL, *nextBuf = NULL; /* Free smart indent macro programs */ EndSmartIndent(window); @@ -983,31 +1058,31 @@ /* Remove any possibly pending callback which might fire after the widget is gone. */ - cancelTimeOut(&window->flashTimeoutID); + cancelTimeOut(&window->editorInfo->flashTimeoutID); cancelTimeOut(&window->markTimeoutID); /* if this is the last window, or must be kept alive temporarily because it's running the macro calling us, don't close it, make it Untitled */ if (keepWindow || (WindowList == window && window->next == NULL)) { - window->filename[0] = '\0'; + window->editorInfo->filename[0] = '\0'; UniqueUntitledName(name); - CLEAR_ALL_LOCKS(window->lockReasons); - window->fileMode = 0; - window->fileUid = 0; - window->fileGid = 0; - strcpy(window->filename, name); - strcpy(window->path, ""); - window->ignoreModify = TRUE; - BufSetAll(window->buffer, ""); - window->ignoreModify = FALSE; + CLEAR_ALL_LOCKS(window->editorInfo->lockReasons); + window->editorInfo->fileMode = 0; + window->editorInfo->fileUid = 0; + window->editorInfo->fileGid = 0; + strcpy(window->editorInfo->filename, name); + strcpy(window->editorInfo->path, ""); + window->editorInfo->ignoreModify = TRUE; + BufSetAll(window->editorInfo->buffer, ""); + window->editorInfo->ignoreModify = FALSE; window->nMarks = 0; - window->filenameSet = FALSE; - window->fileMissing = TRUE; - window->fileChanged = FALSE; - window->fileFormat = UNIX_FILE_FORMAT; - window->lastModTime = 0; - window->device = 0; - window->inode = 0; + window->editorInfo->filenameSet = FALSE; + window->editorInfo->fileMissing = TRUE; + window->editorInfo->fileChanged = FALSE; + window->editorInfo->fileFormat = UNIX_FILE_FORMAT; + window->editorInfo->lastModTime = 0; + window->editorInfo->device = 0; + window->editorInfo->inode = 0; StopHighlighting(window); EndSmartIndent(window); @@ -1027,22 +1102,69 @@ return; } + /* Update the slave window linked list */ + if(window == editorInfo->master) { + /* If we are the master then make the next slave the master. */ + nextSlave = 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) { + nextSlave = w; + w->nextSlave = window->nextSlave; + break; + } + } + } + + /* refresh the clone indexes on the tabs, window and icon titles */ + if (nextSlave) { + selection sel; + Widget w = nextSlave->editorInfo->master->textArea; + Time time = XtLastTimestampProcessed(XtDisplay((Widget)w)); + + /* transfer the primary selection, in case we are closing + the selection owner */ + memcpy(&sel, &window->editorInfo->buffer->primary, sizeof(selection)); + + XtDisownSelection((Widget)window->textArea, XA_PRIMARY, time); + HandleXSelections(w); + + if (sel.selected) { + if (sel.rectangular) + BufRectSelect(nextSlave->editorInfo->buffer, sel.start, sel.end, + sel.rectStart, sel.rectEnd); + else + BufSelect(nextSlave->editorInfo->buffer, sel.start, sel.end); + } else + BufUnselect(nextSlave->editorInfo->buffer); + + /* update assorted titles */ + RefreshWindowStates(nextSlave); + RefreshTabState(nextSlave); + } + /* Free syntax highlighting patterns, if any. w/o redisplaying */ FreeHighlightingData(window); - + + /* if a marker is already drawn, erase it and cancel the timeout */ + if (window->editorInfo->flashTimeoutID != 0) { + BufUnhighlight(window->editorInfo->buffer); + XtRemoveTimeOut(window->editorInfo->flashTimeoutID); + window->editorInfo->flashTimeoutID = 0; + } + /* remove the buffer modification callbacks so the buffer will be deallocated when the last text widget is destroyed */ - BufRemoveModifyCB(window->buffer, modifiedCB, window); - BufRemoveModifyCB(window->buffer, SyntaxHighlightModifyCB, window); + BufRemoveModifyCB(window->editorInfo->buffer, modifiedCB, window); + BufRemoveModifyCB(window->editorInfo->buffer, SyntaxHighlightModifyCB, window); #ifdef ROWCOLPATCH patchRowCol(window->menuBar); #endif - /* free the undo and redo lists */ - ClearUndoList(window); - ClearRedoList(window); - /* close the document/window */ if (NDocuments(window) > 1) { if (MacroRunWindow() && MacroRunWindow() != window @@ -1057,7 +1179,7 @@ topBuf = GetTopDocument(window->shell); } } - + /* remove the window from the global window list, update window menus */ removeFromWindowList(window); InvalidateWindowMenus(); @@ -1092,6 +1214,13 @@ } } + if(editorInfo->master == NULL) { + /* free the undo and redo lists */ + ClearUndoList(window); + ClearRedoList(window); + XtFree((char *)editorInfo); + } + /* free background menu cache for document */ FreeUserBGMenuCache(&window->userBGMenuCache); @@ -1159,8 +1288,8 @@ if (0 == stat(fullname, &attribute)) { for (window = WindowList; window != NULL; window = window->next) { - if (attribute.st_dev == window->device - && attribute.st_ino == window->inode) { + if (attribute.st_dev == window->editorInfo->device + && attribute.st_ino == window->editorInfo->inode) { return window; } } @@ -1170,7 +1299,7 @@ #endif for (window = WindowList; window != NULL; window = window->next) { - if (!strcmp(window->filename, name) && !strcmp(window->path, path)) { + if (!strcmp(window->editorInfo->filename, name) && !strcmp(window->editorInfo->path, path)) { return window; } } @@ -1219,7 +1348,7 @@ text = createTextArea(window->splitPane, window, 1, 1, emTabDist, delimiters, wrapMargin, lineNumCols); - TextSetBuffer(text, window->buffer); + TextSetBuffer(text, window->editorInfo->buffer); if (window->highlightData != NULL) AttachHighlightToWidget(text, window); if (window->backlightChars) @@ -1440,13 +1569,13 @@ void SetTabDist(WindowInfo *window, int tabDist) { - if (window->buffer->tabDist != tabDist) { + if (window->editorInfo->buffer->tabDist != tabDist) { int saveCursorPositions[MAX_PANES + 1]; int saveVScrollPositions[MAX_PANES + 1]; int saveHScrollPositions[MAX_PANES + 1]; int paneIndex; - window->ignoreModify = True; + window->editorInfo->ignoreModify = True; for (paneIndex = 0; paneIndex <= window->nPanes; ++paneIndex) { Widget w = GetPaneByIndex(window, paneIndex); @@ -1457,7 +1586,7 @@ textD->modifyingTabDist = 1; } - BufSetTabDistance(window->buffer, tabDist); + BufSetTabDistance(window->editorInfo->buffer, tabDist); for (paneIndex = 0; paneIndex <= window->nPanes; ++paneIndex) { Widget w = GetPaneByIndex(window, paneIndex); @@ -1468,7 +1597,7 @@ TextSetScroll(w, saveVScrollPositions[paneIndex], saveHScrollPositions[paneIndex]); } - window->ignoreModify = False; + window->editorInfo->ignoreModify = False; } } @@ -1709,23 +1838,28 @@ void SetAutoIndent(WindowInfo *window, int state) { int autoIndent = state == AUTO_INDENT, smartIndent = state == SMART_INDENT; + WindowInfo *w; int i; - if (window->indentStyle == SMART_INDENT && !smartIndent) + if (window->editorInfo->indentStyle == SMART_INDENT && !smartIndent) EndSmartIndent(window); - else if (smartIndent && window->indentStyle != SMART_INDENT) + else if (smartIndent && window->editorInfo->indentStyle != SMART_INDENT) BeginSmartIndent(window, True); - window->indentStyle = state; - XtVaSetValues(window->textArea, textNautoIndent, autoIndent, - textNsmartIndent, smartIndent, NULL); - for (i=0; inPanes; i++) - XtVaSetValues(window->textPanes[i], textNautoIndent, autoIndent, + window->editorInfo->indentStyle = state; + + /* indent style is common among clones */ + for(w = window->editorInfo->master; w; w = w->nextSlave) { + XtVaSetValues(w->textArea, textNautoIndent, autoIndent, textNsmartIndent, smartIndent, NULL); - if (IsTopDocument(window)) { - XmToggleButtonSetState(window->smartIndentItem, smartIndent, False); - XmToggleButtonSetState(window->autoIndentItem, autoIndent, False); - XmToggleButtonSetState(window->autoIndentOffItem, - state == NO_AUTO_INDENT, False); + for (i=0; inPanes; i++) + XtVaSetValues(w->textPanes[i], textNautoIndent, autoIndent, + textNsmartIndent, smartIndent, NULL); + if (IsTopDocument(w)) { + XmToggleButtonSetState(w->smartIndentItem, smartIndent, False); + XmToggleButtonSetState(w->autoIndentItem, autoIndent, False); + XmToggleButtonSetState(w->autoIndentOffItem, + state == NO_AUTO_INDENT, False); + } } } @@ -1735,14 +1869,19 @@ */ void SetShowMatching(WindowInfo *window, int state) { - window->showMatchingStyle = state; - if (IsTopDocument(window)) { - XmToggleButtonSetState(window->showMatchingOffItem, - state == NO_FLASH, False); - XmToggleButtonSetState(window->showMatchingDelimitItem, - state == FLASH_DELIMIT, False); - XmToggleButtonSetState(window->showMatchingRangeItem, - state == FLASH_RANGE, False); + WindowInfo *w; + window->editorInfo->showMatchingStyle = state; + + /* matching style is common among clones */ + for(w = window->editorInfo->master; w; w = w->nextSlave) { + if (IsTopDocument(w)) { + XmToggleButtonSetState(w->showMatchingOffItem, + state == NO_FLASH, False); + XmToggleButtonSetState(w->showMatchingDelimitItem, + state == FLASH_DELIMIT, False); + XmToggleButtonSetState(w->showMatchingRangeItem, + state == FLASH_RANGE, False); + } } } @@ -1931,7 +2070,7 @@ XtVaSetValues(window->textArea, textNoverstrike, overstrike, NULL); for (i=0; inPanes; i++) XtVaSetValues(window->textPanes[i], textNoverstrike, overstrike, NULL); - window->overstrike = overstrike; + window->editorInfo->overstrike = overstrike; } /* @@ -1947,7 +2086,7 @@ for (i=0; inPanes; i++) XtVaSetValues(window->textPanes[i], textNautoWrap, autoWrap, textNcontinuousWrap, contWrap, NULL); - window->wrapMode = state; + window->editorInfo->wrapMode = state; if (IsTopDocument(window)) { XmToggleButtonSetState(window->newlineWrapItem, autoWrap, False); @@ -2015,19 +2154,37 @@ return window; } +int GetCloneIndex(const WindowInfo *window) +{ + WindowInfo *w; + int num = 0; + + if (!window->editorInfo->master->nextSlave) + return 0; + + for(w = window->editorInfo->master; w; w = w->nextSlave) { + num++; + if(w == window) + break; + } + return num; +} + /* ** Change the window appearance and the window data structure to show ** that the file it contains has been modified */ void SetWindowModified(WindowInfo *window, int modified) { - if (window->fileChanged == FALSE && modified == TRUE) { - SetSensitive(window, window->closeItem, TRUE); - window->fileChanged = TRUE; + if (window->editorInfo->fileChanged == FALSE && modified == TRUE) { + WindowInfo *w; + for(w = window->editorInfo->master; w; w = w->nextSlave) + SetSensitive(window, w->closeItem, TRUE); + window->editorInfo->fileChanged = TRUE; UpdateWindowTitle(window); RefreshTabState(window); - } else if (window->fileChanged == TRUE && modified == FALSE) { - window->fileChanged = FALSE; + } else if (window->editorInfo->fileChanged == TRUE && modified == FALSE) { + window->editorInfo->fileChanged = FALSE; UpdateWindowTitle(window); RefreshTabState(window); } @@ -2037,15 +2194,29 @@ ** Update the window title to reflect the filename, read-only, and modified ** status of the window data structure */ -void UpdateWindowTitle(const WindowInfo *window) +void _updateWindowTitle(const WindowInfo *window) { char *iconTitle, *title; + char *filename; if (!IsTopDocument(window)) return; - title = FormatWindowTitle(window->filename, - window->path, + if (GetCloneIndex(window) > 0) { + char buf[10]; + sprintf(buf, "<%d>", GetCloneIndex(window)); + filename = XtMalloc(strlen(window->editorInfo->filename) + + strlen(buf) + 2); /* strlen("*")+1 */ + strcpy(filename, window->editorInfo->filename); + strcat(filename, buf); + } + else { + filename = XtMalloc(strlen(window->editorInfo->filename) + 2); /* strlen("*")+1 */ + strcpy(filename, window->editorInfo->filename); + } + + title = FormatWindowTitle( filename, + window->editorInfo->path, #ifdef VMS NULL, #else @@ -2053,53 +2224,68 @@ #endif /* VMS */ GetPrefServerName(), IsServer, - window->filenameSet, - window->lockReasons, - window->fileChanged, + window->editorInfo->filenameSet, + window->editorInfo->lockReasons, + window->editorInfo->fileChanged, GetPrefTitleFormat()); - iconTitle = XtMalloc(strlen(window->filename) + 2); /* strlen("*")+1 */ + iconTitle = XtMalloc(strlen(filename) + 2); /* strlen("*")+1 */ - strcpy(iconTitle, window->filename); - if (window->fileChanged) + strcpy(iconTitle, filename); + if (window->editorInfo->fileChanged) strcat(iconTitle, "*"); XtVaSetValues(window->shell, XmNtitle, title, XmNiconName, iconTitle, NULL); /* 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); + sprintf(title, "Find (in %s)", window->editorInfo->filename); XtVaSetValues(XtParent(window->findDlog), XmNtitle, title, NULL); } if (window->replaceDlog && XmToggleButtonGetState(window->replaceKeepBtn)) { - sprintf(title, "Replace (in %s)", window->filename); + sprintf(title, "Replace (in %s)", window->editorInfo->filename); XtVaSetValues(XtParent(window->replaceDlog), XmNtitle, title, NULL); } XtFree(iconTitle); + XtFree(filename); /* Update the Windows menus with the new name */ InvalidateWindowMenus(); } +void UpdateWindowTitle(const WindowInfo *window) +{ + WindowInfo *w; + for(w = window->editorInfo->master; w; w = w->nextSlave) + _updateWindowTitle(w); +} + /* ** Update the read-only state of the text area(s) in the window, and ** the ReadOnly toggle button in the File menu to agree with the state in ** the window data structure. */ -void UpdateWindowReadOnly(WindowInfo *window) +void _updateWindowReadOnly(WindowInfo *window) { int i, state; if (!IsTopDocument(window)) return; - state = IS_ANY_LOCKED(window->lockReasons); + state = IS_ANY_LOCKED(window->editorInfo->lockReasons); XtVaSetValues(window->textArea, textNreadOnly, state, NULL); for (i=0; inPanes; i++) XtVaSetValues(window->textPanes[i], textNreadOnly, state, NULL); XmToggleButtonSetState(window->readOnlyItem, state, FALSE); XtSetSensitive(window->readOnlyItem, - !IS_ANY_LOCKED_IGNORING_USER(window->lockReasons)); + !IS_ANY_LOCKED_IGNORING_USER(window->editorInfo->lockReasons)); +} + +void UpdateWindowReadOnly(WindowInfo *window) +{ + WindowInfo *w; + for(w = window->editorInfo->master; w; w = w->nextSlave) + _updateWindowReadOnly(w); } /* @@ -2146,7 +2332,7 @@ Dimension width; /* find out where the selection is */ - if (!BufGetSelectionPos(window->buffer, &left, &right, &isRect, + if (!BufGetSelectionPos(window->editorInfo->buffer, &left, &right, &isRect, &rectStart, &rectEnd)) { left = right = TextGetCursorPos(textPane); isRect = False; @@ -2246,14 +2432,14 @@ textNemulateTabs, emTabDist, textNfont, GetDefaultFontStruct(window->fontList), textNhScrollBar, hScrollBar, textNvScrollBar, vScrollBar, - textNreadOnly, IS_ANY_LOCKED(window->lockReasons), + textNreadOnly, IS_ANY_LOCKED(window->editorInfo->lockReasons), 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, + 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, textNhidePointer, (Boolean) GetPrefTypingHidesPointer(), textNcursorVPadding, GetVerticalAutoScroll(), NULL); @@ -2293,7 +2479,7 @@ { TextWidget textWidget = (TextWidget) w; - if (window->ignoreModify) + if (window->editorInfo->ignoreModify) return; /* update line and column nubers in statistics line */ @@ -2321,10 +2507,11 @@ const char *deletedText, void *cbArg) { WindowInfo *window = (WindowInfo *)cbArg; - int selected = window->buffer->primary.selected; + int selected = window->editorInfo->buffer->primary.selected; + int isUndo = (window->editorInfo->undo != NULL && window->editorInfo->undo->inUndo); /* update the table of bookmarks */ - if (!window->ignoreModify) { + if (!window->editorInfo->ignoreModify) { UpdateMarkTable(window, pos, nInserted, nDeleted); } @@ -2359,7 +2546,7 @@ /* When the program needs to make a change to a text area without without recording it for undo or marking file as changed it sets ignoreModify */ - if (window->ignoreModify || (nDeleted == 0 && nInserted == 0)) + if (window->editorInfo->ignoreModify || (nDeleted == 0 && nInserted == 0)) return; /* Make sure line number display is sufficient for new data */ @@ -2370,16 +2557,19 @@ 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)) { + if (window->editorInfo->autoSave && + (window->editorInfo->autoSaveCharCount > AUTOSAVE_CHAR_LIMIT || + window->editorInfo->autoSaveOpCount > AUTOSAVE_OP_LIMIT)) { WriteBackupFile(window); - window->autoSaveCharCount = 0; - window->autoSaveOpCount = 0; + window->editorInfo->autoSaveCharCount = 0; + window->editorInfo->autoSaveOpCount = 0; } /* Indicate that the window has now been modified */ - SetWindowModified(window, TRUE); + if (isUndo && window->editorInfo->undo->restoresToSaved) + SetWindowModified(window, False); + else + SetWindowModified(window, TRUE); /* Update # of bytes, and line and col statistics */ UpdateStatsLine(window); @@ -2406,13 +2596,13 @@ static void dragStartCB(Widget w, WindowInfo *window, XtPointer callData) { /* don't record all of the intermediate drag steps for undo */ - window->ignoreModify = True; + window->editorInfo->ignoreModify = True; } static void dragEndCB(Widget w, WindowInfo *window, dragEndCBStruct *callData) { /* restore recording of undo information */ - window->ignoreModify = False; + window->editorInfo->ignoreModify = False; /* Do nothing if drag operation was canceled */ if (callData->nCharsInserted == 0) @@ -2502,11 +2692,11 @@ for (i=0; i< tabCount; i++) { win = TabToWindow(tabs[i]); - if (win->filenameSet) { + if (win->editorInfo->filenameSet) { /* add filename */ - argv[argc] = XtMalloc(strlen(win->path) + - strlen(win->filename) + 1); - sprintf(argv[argc++], "%s%s", win->path, win->filename); + argv[argc] = XtMalloc(strlen(win->editorInfo->path) + + strlen(win->editorInfo->filename) + 1); + sprintf(argv[argc++], "%s%s", win->editorInfo->path, win->editorInfo->filename); } } } @@ -2562,6 +2752,17 @@ return result; } +static void addToCloneList(WindowInfo *window) +{ + WindowInfo *w; + + /* Add window to end of slave list */ + for(w = window->editorInfo->master; w->nextSlave != NULL; w = w->nextSlave) + ; + w->nextSlave = window; + window->nextSlave = NULL; +} + /* ** Add a window to the the window list. */ @@ -2714,22 +2915,22 @@ /* Compose the string to display. If line # isn't available, leave it off */ pos = TextGetCursorPos(window->lastFocus); - string = XtMalloc(strlen(window->filename) + strlen(window->path) + 45); - format = window->fileFormat == DOS_FILE_FORMAT ? " DOS" : - (window->fileFormat == MAC_FILE_FORMAT ? " Mac" : ""); + string = XtMalloc(strlen(window->editorInfo->filename) + strlen(window->editorInfo->path) + 45); + format = window->editorInfo->fileFormat == DOS_FILE_FORMAT ? " DOS" : + (window->editorInfo->fileFormat == MAC_FILE_FORMAT ? " Mac" : ""); if (!TextPosToLineAndCol(window->lastFocus, pos, &line, &colNum)) { - sprintf(string, "%s%s%s %d bytes", window->path, window->filename, - format, window->buffer->length); + sprintf(string, "%s%s%s %d bytes", window->editorInfo->path, window->editorInfo->filename, + format, window->editorInfo->buffer->length); sprintf(slinecol, "L: --- C: ---"); } else { sprintf(slinecol, "L: %d C: %d", line, colNum); if (window->showLineNumbers) - sprintf(string, "%s%s%s byte %d of %d", window->path, - window->filename, format, pos, - window->buffer->length); + sprintf(string, "%s%s%s byte %d of %d", window->editorInfo->path, + window->editorInfo->filename, format, pos, + window->editorInfo->buffer->length); else - sprintf(string, "%s%s%s %d bytes", window->path, - window->filename, format, window->buffer->length); + sprintf(string, "%s%s%s %d bytes", window->editorInfo->path, + window->editorInfo->filename, format, window->editorInfo->buffer->length); } /* Update the line/column number */ @@ -3250,7 +3451,8 @@ ** unnecessarily; hence speeding up the process of opening ** multiple files. */ -WindowInfo* CreateDocument(WindowInfo* shellWindow, const char* name) +WindowInfo* CreateDocument(WindowInfo* shellWindow, const char* name, + EditorInfo *editorInfo) { Widget pane, text; WindowInfo *window; @@ -3262,6 +3464,40 @@ /* inherit settings and later reset those required */ memcpy(window, shellWindow, sizeof(WindowInfo)); + if(editorInfo) { + /* share editorInfo among clones */ + window->editorInfo = editorInfo; + } + else { + window->editorInfo = (EditorInfo *)XtMalloc(sizeof(EditorInfo)); + window->editorInfo->master = window; + window->editorInfo->fileChanged = FALSE; + window->editorInfo->filenameSet = FALSE; + strcpy(window->editorInfo->filename, name); + 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->indentStyle = GetPrefAutoIndent(PLAIN_LANGUAGE_MODE); + window->editorInfo->autoSave = GetPrefAutoSave(); + window->editorInfo->saveOldVersion = GetPrefSaveOldVersion(); + window->editorInfo->wrapMode = GetPrefWrap(PLAIN_LANGUAGE_MODE); + window->editorInfo->overstrike = False; + window->editorInfo->ignoreModify = FALSE; + window->editorInfo->flashTimeoutID = 0; + CLEAR_ALL_LOCKS(window->editorInfo->lockReasons); + window->editorInfo->smartIndentData = NULL; + window->editorInfo->fileClosedAtom = None; + window->editorInfo->fileMode = 0; + window->editorInfo->fileFormat = UNIX_FILE_FORMAT; + window->editorInfo->lastModTime = 0; + window->editorInfo->fileMissing = True; + window->editorInfo->showMatchingStyle = GetPrefShowMatching(); + window->editorInfo->matchSyntaxBased = GetPrefMatchSyntaxBased(); + } + #if 0 /* share these dialog items with parent shell */ window->replaceDlog = NULL; @@ -3283,34 +3519,12 @@ window->showISearchLine = GetPrefISearchLine(); #endif + window->nextSlave = NULL; window->multiFileReplSelected = FALSE; window->multiFileBusy = FALSE; window->writableWindows = NULL; window->nWritableWindows = 0; - window->fileChanged = FALSE; - window->fileMissing = True; - window->fileMode = 0; - window->fileUid = 0; - window->fileGid = 0; - window->filenameSet = FALSE; - window->fileFormat = UNIX_FILE_FORMAT; - window->lastModTime = 0; - 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; - CLEAR_ALL_LOCKS(window->lockReasons); - window->indentStyle = GetPrefAutoIndent(PLAIN_LANGUAGE_MODE); - window->autoSave = GetPrefAutoSave(); - window->saveOldVersion = GetPrefSaveOldVersion(); - window->wrapMode = GetPrefWrap(PLAIN_LANGUAGE_MODE); - window->overstrike = False; - window->showMatchingStyle = GetPrefShowMatching(); - window->matchSyntaxBased = GetPrefMatchSyntaxBased(); window->highlightSyntax = GetPrefHighlightSyntax(); window->backlightCharTypes = NULL; window->backlightChars = GetPrefBacklightChars(); @@ -3323,10 +3537,7 @@ } window->modeMessageDisplayed = FALSE; window->modeMessage = NULL; - window->ignoreModify = FALSE; window->windowMenuValid = FALSE; - window->flashTimeoutID = 0; - window->fileClosedAtom = None; window->wasSelected = FALSE; strcpy(window->fontName, GetPrefFontName()); strcpy(window->italicFontName, GetPrefItalicFontName()); @@ -3343,7 +3554,6 @@ window->highlightData = NULL; window->shellCmdData = NULL; window->macroCmdData = NULL; - window->smartIndentData = NULL; window->languageMode = PLAIN_LANGUAGE_MODE; window->iSearchHistIndex = 0; window->iSearchStartPos = -1; @@ -3356,8 +3566,6 @@ window->tab = NULL; window->bgMenuUndoItem = NULL; window->bgMenuRedoItem = NULL; - window->device = 0; - window->inode = 0; if (window->fontList == NULL) XtVaGetValues(shellWindow->statsLine, XmNfontList, @@ -3428,24 +3636,30 @@ with the text area widget. This is done so the syntax highlighting modify callback can be called to synchronize the style buffer BEFORE the text display's callback is called upon to display a modification */ - window->buffer = BufCreate(); - BufAddModifyCB(window->buffer, SyntaxHighlightModifyCB, window); + 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->buffer); - BufAddModifyCB(window->buffer, modifiedCB, window); + TextSetBuffer(text, window->editorInfo->buffer); + BufAddModifyCB(window->editorInfo->buffer, modifiedCB, window); /* Designate the permanent text area as the owner for selections */ - HandleXSelections(text); + if (!editorInfo) + 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(); + window->editorInfo->ignoreModify = True; + BufSetTabDistance(window->editorInfo->buffer, GetPrefTabDist(PLAIN_LANGUAGE_MODE)); + window->editorInfo->ignoreModify = False; + window->editorInfo->buffer->useTabs = GetPrefInsertTabs(); window->tab = addTab(window->tabBar, name); /* add the window to the global window list, update the Windows menus */ InvalidateWindowMenus(); addToWindowList(window); + if (editorInfo) + addToCloneList(window); #ifdef LESSTIF_VERSION /* FIXME: Temporary workaround for disappearing-text-window bug @@ -3583,24 +3797,32 @@ /* ** update the tab label, etc. of a tab, per the states of it's document. */ -void RefreshTabState(WindowInfo *win) +void _RefreshTabState(WindowInfo *win) { XmString s1, tipString; char labelString[MAXPATHLEN]; char *tag = XmFONTLIST_DEFAULT_TAG; unsigned char alignment; - + char cloneIndex[10]; + + if (GetCloneIndex(win) > 0) { + sprintf(cloneIndex, "<%d>", GetCloneIndex(win)); + } else { + cloneIndex[0] = '\0'; + } + /* Set tab label to document's filename. Position of "*" (modified) will change per label alignment setting */ XtVaGetValues(win->tab, XmNalignment, &alignment, NULL); if (alignment != XmALIGNMENT_END) { - sprintf(labelString, "%s%s", - win->fileChanged? "*" : "", - win->filename); + sprintf(labelString, "%s%s%s", + win->editorInfo->fileChanged? "*" : "", + win->editorInfo->filename, cloneIndex); } else { - sprintf(labelString, "%s%s", - win->filename, - win->fileChanged? "*" : ""); + sprintf(labelString, "%s%s%s", + win->editorInfo->filename, + cloneIndex, + win->editorInfo->fileChanged? "*" : ""); } /* Make the top document stand out a little more */ @@ -3609,9 +3831,9 @@ s1 = XmStringCreateLtoR(labelString, tag); - if (GetPrefShowPathInWindowsMenu() && win->filenameSet) { + if (GetPrefShowPathInWindowsMenu() && win->editorInfo->filenameSet) { strcat(labelString, " - "); - strcat(labelString, win->path); + strcat(labelString, win->editorInfo->path); } tipString=XmStringCreateSimple(labelString); @@ -3623,6 +3845,12 @@ XmStringFree(tipString); } +void RefreshTabState(WindowInfo *win) +{ + WindowInfo *w; + for(w = win->editorInfo->master; w; w = w->nextSlave) + _RefreshTabState(w); +} /* ** close all the documents in a window */ @@ -3640,7 +3868,7 @@ /* close all _modified_ documents belong to this window */ for (win = WindowList; win; ) { - if (win->shell == winShell && win->fileChanged) { + if (win->shell == winShell && win->editorInfo->fileChanged) { WindowInfo *next = win->next; if (!CloseFileAndWindow(win, PROMPT_SBC_DIALOG_RESPONSE)) return False; @@ -3719,8 +3947,8 @@ XtSetSensitive(window->printSelItem, window->wasSelected); /* Edit menu */ - XtSetSensitive(window->undoItem, window->undo != NULL); - XtSetSensitive(window->redoItem, window->redo != NULL); + XtSetSensitive(window->undoItem, window->editorInfo->undo != NULL); + XtSetSensitive(window->redoItem, window->editorInfo->redo != NULL); XtSetSensitive(window->printSelItem, window->wasSelected); XtSetSensitive(window->cutItem, window->wasSelected); XtSetSensitive(window->copyItem, window->wasSelected); @@ -3734,19 +3962,19 @@ XtSetSensitive(window->highlightItem, window->languageMode != PLAIN_LANGUAGE_MODE); XmToggleButtonSetState(window->backlightCharsItem, window->backlightChars, False); #ifndef VMS - XmToggleButtonSetState(window->saveLastItem, window->saveOldVersion, False); + XmToggleButtonSetState(window->saveLastItem, window->editorInfo->saveOldVersion, False); #endif - XmToggleButtonSetState(window->autoSaveItem, window->autoSave, False); - XmToggleButtonSetState(window->overtypeModeItem, window->overstrike, False); - XmToggleButtonSetState(window->matchSyntaxBasedItem, window->matchSyntaxBased, False); - XmToggleButtonSetState(window->readOnlyItem, IS_USER_LOCKED(window->lockReasons), False); + XmToggleButtonSetState(window->autoSaveItem, window->editorInfo->autoSave, False); + XmToggleButtonSetState(window->overtypeModeItem, window->editorInfo->overstrike, False); + XmToggleButtonSetState(window->matchSyntaxBasedItem, window->editorInfo->matchSyntaxBased, False); + XmToggleButtonSetState(window->readOnlyItem, IS_USER_LOCKED(window->editorInfo->lockReasons), False); XtSetSensitive(window->smartIndentItem, SmartIndentMacrosAvailable(LanguageModeName(window->languageMode))); - SetAutoIndent(window, window->indentStyle); - SetAutoWrap(window, window->wrapMode); - SetShowMatching(window, window->showMatchingStyle); + SetAutoIndent(window, window->editorInfo->indentStyle); + SetAutoWrap(window, window->editorInfo->wrapMode); + SetShowMatching(window, window->editorInfo->showMatchingStyle); SetLanguageMode(window, window->languageMode, FALSE); /* Windows Menu */ @@ -4138,16 +4366,16 @@ textDisp *textD, *newTextD; /* transfer the primary selection */ - memcpy(&sel, &orgWin->buffer->primary, sizeof(selection)); + memcpy(&sel, &orgWin->editorInfo->buffer->primary, sizeof(selection)); if (sel.selected) { if (sel.rectangular) - BufRectSelect(window->buffer, sel.start, sel.end, + BufRectSelect(window->editorInfo->buffer, sel.start, sel.end, sel.rectStart, sel.rectEnd); else - BufSelect(window->buffer, sel.start, sel.end); + BufSelect(window->editorInfo->buffer, sel.start, sel.end); } else - BufUnselect(window->buffer); + BufUnselect(window->editorInfo->buffer); /* Record the current heights, scroll positions, and insert positions of the existing panes, keyboard focus */ @@ -4187,7 +4415,7 @@ for(i=0; inPanes; i++) { text = createTextArea(window->splitPane, window, 1, 1, emTabDist, delimiters, wrapMargin, lineNumCols); - TextSetBuffer(text, window->buffer); + TextSetBuffer(text, window->editorInfo->buffer); if (window->highlightData != NULL) AttachHighlightToWidget(text, window); @@ -4250,30 +4478,30 @@ /* ** clone a document's states and settings into the other. */ -static void cloneDocument(WindowInfo *window, WindowInfo *orgWin) +static void mirrorDocumentStates(WindowInfo *window, WindowInfo *orgWin) { const char *orgDocument; char *params[4]; int emTabDist; - strcpy(window->path, orgWin->path); - strcpy(window->filename, orgWin->filename); + strcpy(window->editorInfo->path, orgWin->editorInfo->path); + strcpy(window->editorInfo->filename, orgWin->editorInfo->filename); ShowLineNumbers(window, orgWin->showLineNumbers); - window->ignoreModify = True; + window->editorInfo->ignoreModify = True; /* copy the text buffer */ - orgDocument = BufAsString(orgWin->buffer); - BufSetAll(window->buffer, orgDocument); + orgDocument = BufAsString(orgWin->editorInfo->buffer); + BufSetAll(window->editorInfo->buffer, orgDocument); /* copy the tab preferences (here!) */ - BufSetTabDistance(window->buffer, orgWin->buffer->tabDist); - window->buffer->useTabs = orgWin->buffer->useTabs; + BufSetTabDistance(window->editorInfo->buffer, orgWin->editorInfo->buffer->tabDist); + window->editorInfo->buffer->useTabs = orgWin->editorInfo->buffer->useTabs; XtVaGetValues(orgWin->textArea, textNemulateTabs, &emTabDist, NULL); SetEmTabDist(window, emTabDist); - window->ignoreModify = False; + window->editorInfo->ignoreModify = False; /* transfer text fonts */ params[0] = orgWin->fontName; @@ -4291,8 +4519,8 @@ else the rangesets do not be highlighted (colored) properly if syntax highlighting is on. */ - window->buffer->rangesetTable = - RangesetTableClone(orgWin->buffer->rangesetTable, window->buffer); + window->editorInfo->buffer->rangesetTable = + RangesetTableClone(orgWin->editorInfo->buffer->rangesetTable, window->editorInfo->buffer); /* Syntax highlighting */ window->languageMode = orgWin->languageMode; @@ -4301,31 +4529,31 @@ StartHighlighting(window, False); /* copy states of original document */ - window->filenameSet = orgWin->filenameSet; - window->fileFormat = orgWin->fileFormat; - window->lastModTime = orgWin->lastModTime; - window->fileChanged = orgWin->fileChanged; - window->fileMissing = orgWin->fileMissing; - window->lockReasons = orgWin->lockReasons; - window->autoSaveCharCount = orgWin->autoSaveCharCount; - window->autoSaveOpCount = orgWin->autoSaveOpCount; - window->undoOpCount = orgWin->undoOpCount; - window->undoMemUsed = orgWin->undoMemUsed; - window->lockReasons = orgWin->lockReasons; - window->autoSave = orgWin->autoSave; - window->saveOldVersion = orgWin->saveOldVersion; - window->wrapMode = orgWin->wrapMode; - SetOverstrike(window, orgWin->overstrike); - window->showMatchingStyle = orgWin->showMatchingStyle; - window->matchSyntaxBased = orgWin->matchSyntaxBased; + window->editorInfo->filenameSet = orgWin->editorInfo->filenameSet; + window->editorInfo->fileFormat = orgWin->editorInfo->fileFormat; + window->editorInfo->lastModTime = orgWin->editorInfo->lastModTime; + window->editorInfo->fileChanged = orgWin->editorInfo->fileChanged; + window->editorInfo->fileMissing = orgWin->editorInfo->fileMissing; + window->editorInfo->lockReasons = orgWin->editorInfo->lockReasons; + window->editorInfo->autoSaveCharCount = orgWin->editorInfo->autoSaveCharCount; + window->editorInfo->autoSaveOpCount = orgWin->editorInfo->autoSaveOpCount; + window->editorInfo->undoOpCount = orgWin->editorInfo->undoOpCount; + window->editorInfo->undoMemUsed = orgWin->editorInfo->undoMemUsed; + window->editorInfo->lockReasons = orgWin->editorInfo->lockReasons; + window->editorInfo->autoSave = orgWin->editorInfo->autoSave; + window->editorInfo->saveOldVersion = orgWin->editorInfo->saveOldVersion; + window->editorInfo->wrapMode = orgWin->editorInfo->wrapMode; + SetOverstrike(window, orgWin->editorInfo->overstrike); + window->editorInfo->showMatchingStyle = orgWin->editorInfo->showMatchingStyle; + window->editorInfo->matchSyntaxBased = orgWin->editorInfo->matchSyntaxBased; #if 0 window->showStats = orgWin->showStats; window->showISearchLine = orgWin->showISearchLine; window->showLineNumbers = orgWin->showLineNumbers; window->modeMessageDisplayed = orgWin->modeMessageDisplayed; - window->ignoreModify = orgWin->ignoreModify; + window->editorInfo->ignoreModify = orgWin->editorInfo->ignoreModify; window->windowMenuValid = orgWin->windowMenuValid; - window->flashTimeoutID = orgWin->flashTimeoutID; + window->editorInfo->flashTimeoutID = orgWin->editorInfo->flashTimeoutID; window->wasSelected = orgWin->wasSelected; strcpy(window->fontName, orgWin->fontName); strcpy(window->italicFontName, orgWin->italicFontName); @@ -4339,7 +4567,7 @@ window->highlightData = orgWin->highlightData; window->shellCmdData = orgWin->shellCmdData; window->macroCmdData = orgWin->macroCmdData; - window->smartIndentData = orgWin->smartIndentData; + window->editorInfo->smartIndentData = orgWin->editorInfo->smartIndentData; #endif window->iSearchHistIndex = orgWin->iSearchHistIndex; window->iSearchStartPos = orgWin->iSearchStartPos; @@ -4349,17 +4577,17 @@ window->iSearchLastLiteralCase = orgWin->iSearchLastLiteralCase; window->findLastRegexCase = orgWin->findLastRegexCase; window->findLastLiteralCase = orgWin->findLastLiteralCase; - window->device = orgWin->device; - window->inode = orgWin->inode; - window->fileClosedAtom = orgWin->fileClosedAtom; - orgWin->fileClosedAtom = None; + window->editorInfo->device = orgWin->editorInfo->device; + window->editorInfo->inode = orgWin->editorInfo->inode; + window->editorInfo->fileClosedAtom = orgWin->editorInfo->fileClosedAtom; + orgWin->editorInfo->fileClosedAtom = None; /* copy the text/split panes settings, cursor pos & selection */ cloneTextPanes(window, orgWin); /* copy undo & redo list */ - window->undo = cloneUndoItems(orgWin->undo); - window->redo = cloneUndoItems(orgWin->redo); + window->editorInfo->undo = cloneUndoItems(orgWin->editorInfo->undo); + window->editorInfo->redo = cloneUndoItems(orgWin->editorInfo->redo); /* copy bookmarks */ window->nMarks = orgWin->nMarks; @@ -4367,13 +4595,61 @@ sizeof(Bookmark)*window->nMarks); /* kick start the auto-indent engine */ - window->indentStyle = NO_AUTO_INDENT; - SetAutoIndent(window, orgWin->indentStyle); + window->editorInfo->indentStyle = NO_AUTO_INDENT; + SetAutoIndent(window, orgWin->editorInfo->indentStyle); /* synchronize window state to this document */ RefreshWindowStates(window); } +static void shareBufferOnCloning(WindowInfo *window, WindowInfo *orgWin) +{ + char *params[4]; + + strcpy(window->editorInfo->path, orgWin->editorInfo->path); + strcpy(window->editorInfo->filename, orgWin->editorInfo->filename); + + ShowLineNumbers(window, orgWin->showLineNumbers); + + /* transfer text fonts */ + params[0] = orgWin->fontName; + params[1] = orgWin->italicFontName; + params[2] = orgWin->boldFontName; + params[3] = orgWin->boldItalicFontName; + XtCallActionProc(window->textArea, "set_fonts", NULL, params, 4); + + SetBacklightChars(window, orgWin->backlightCharTypes); + + /* Syntax highlighting. Clones may use different language mode */ + window->languageMode = orgWin->languageMode; + window->highlightSyntax = orgWin->highlightSyntax; + if (window->highlightSyntax) + StartHighlighting(window, False); + + /* clone original buffer's states */ + window->nPanes = orgWin->nPanes; + window->highlightSyntax = orgWin->highlightSyntax; + window->iSearchHistIndex = orgWin->iSearchHistIndex; + window->iSearchStartPos = orgWin->iSearchStartPos; + window->replaceLastRegexCase = orgWin->replaceLastRegexCase; + window->replaceLastLiteralCase = orgWin->replaceLastLiteralCase; + window->iSearchLastRegexCase = orgWin->iSearchLastRegexCase; + window->iSearchLastLiteralCase = orgWin->iSearchLastLiteralCase; + window->findLastRegexCase = orgWin->findLastRegexCase; + window->findLastLiteralCase = orgWin->findLastLiteralCase; + + /* copy the text/split panes settings, cursor pos & selection */ + cloneTextPanes(window, orgWin); + + /* copy bookmarks */ + window->nMarks = orgWin->nMarks; + memcpy(&window->markTable, &orgWin->markTable, + sizeof(Bookmark)*window->nMarks); + + /* synchronize window state to this buffer */ + RefreshWindowStates(window); +} + static UndoInfo *cloneUndoItems(UndoInfo *orgList) { UndoInfo *head = NULL, *undo, *clone, *last = NULL; @@ -4417,7 +4693,13 @@ } /* Create a new window */ - cloneWin = CreateWindow(window->filename, NULL, False); + if (window->editorInfo->master->nextSlave) { + cloneWin = CreateWindow(window->editorInfo->filename, NULL, + False, window->editorInfo); + } else { + cloneWin = CreateWindow(window->editorInfo->filename, NULL, + False, NULL); + } /* CreateWindow() simply adds the new window's pointer to the head of WindowList. We need to adjust the detached window's @@ -4436,10 +4718,14 @@ ShowStatsLine(cloneWin, window->showStats); /* clone the document & its pref settings */ - cloneDocument(cloneWin, window); + if (window->editorInfo->master->nextSlave) + shareBufferOnCloning(cloneWin, window); + else + mirrorDocumentStates(cloneWin, window); /* remove the document from the old window */ - window->fileChanged = False; + if (window->editorInfo->master->nextSlave == NULL) + window->editorInfo->fileChanged = False; CloseFileAndWindow(window, NO_SBC_DIALOG_RESPONSE); /* refresh former host window */ @@ -4455,6 +4741,21 @@ return cloneWin; } +int isSafeToMove(WindowInfo *toWindow, WindowInfo *window) +{ + /* FIXME: moving a clone can be very complicated, so + for now we just don't do it. */ + if (window->editorInfo->master->nextSlave) { + WindowInfo *w; + for(w = WindowList; w; w = w->next) { + if (w->shell == toWindow->shell && w->editorInfo == window->editorInfo) + return False; + } + } + + return True; +} + /* ** Move document to an other window. ** @@ -4477,9 +4778,19 @@ } /* relocate the document to target window */ - cloneWin = CreateDocument(toWindow, window->filename); + if (window->editorInfo->master->nextSlave) { + cloneWin = CreateDocument(toWindow, window->editorInfo->filename, window->editorInfo); + } else { + cloneWin = CreateDocument(toWindow, window->editorInfo->filename, NULL); + } ShowTabBar(cloneWin, GetShowTabBar(cloneWin)); - cloneDocument(cloneWin, window); + + if (window->editorInfo->master->nextSlave) { + shareBufferOnCloning(cloneWin, window); + } + else { + mirrorDocumentStates(cloneWin, window); + } /* CreateDocument() simply adds the new window's pointer to the head of WindowList. We need to adjust the detached window's @@ -4492,7 +4803,8 @@ window->next = cloneWin; /* remove the document from the old window */ - window->fileChanged = False; + if (window->editorInfo->master->nextSlave == NULL) + window->editorInfo->fileChanged = False; CloseFileAndWindow(window, NO_SBC_DIALOG_RESPONSE); /* some menu states might have changed when deleting document */ @@ -4540,7 +4852,7 @@ continue; sprintf(tmpStr, "%s%s", - win->filenameSet? win->path : "", win->filename); + win->editorInfo->filenameSet? win->editorInfo->path : "", win->editorInfo->filename); list[nList] = XmStringCreateSimple(tmpStr); shellWinList[nList] = win; @@ -4557,7 +4869,7 @@ /* create the dialog */ parent = window->shell; popupTitle = XmStringCreateSimple("Move Document"); - sprintf(tmpStr, "Move %s into window of", window->filename); + sprintf(tmpStr, "Move %s into window of", window->editorInfo->filename); s1 = XmStringCreateSimple(tmpStr); ac = 0; XtSetArg(csdargs[ac], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); ac++; diff -ur nedit_official/source/window.h nedit_mod/source/window.h --- nedit_official/source/window.h 2008-01-04 23:11:05.000000000 +0100 +++ nedit_mod/source/window.h 2008-03-17 23:50:03.000000000 +0100 @@ -33,8 +33,11 @@ #include +int GetCloneIndex(const WindowInfo *window); +WindowInfo *CreateCloneWindow(WindowInfo *window); void AttachSessionMgrHandler(Widget appShell); -WindowInfo *CreateWindow(const char *title, char *geometry, int iconic); +WindowInfo *CreateWindow(const char *name, char *geometry, int iconic, + EditorInfo *editorInfo); void CloseWindow(WindowInfo *window); int NWindows(void); void UpdateWindowTitle(const WindowInfo *window); @@ -74,7 +77,8 @@ void SetTabDist(WindowInfo *window, int tabDist); void SetEmTabDist(WindowInfo *window, int emTabDist); int CloseAllDocumentInWindow(WindowInfo *window); -WindowInfo* CreateDocument(WindowInfo* shellWindow, const char* name); +WindowInfo* CreateDocument(WindowInfo* shellWindow, const char* name, + EditorInfo *editorInfo); WindowInfo *TabToWindow(Widget tab); void RaiseDocument(WindowInfo *window); void RaiseDocumentWindow(WindowInfo *window); diff -ur nedit_official/source/windowTitle.c nedit_mod/source/windowTitle.c --- nedit_official/source/windowTitle.c 2007-12-31 12:12:44.000000000 +0100 +++ nedit_mod/source/windowTitle.c 2008-03-17 23:50:03.000000000 +0100 @@ -234,7 +234,6 @@ } while (modified == True); } - /* ** Format the windows title using a printf like formatting string. ** The following flags are recognised: @@ -1443,8 +1442,8 @@ * 'real world' defaults as possible when testing the effect * of different formatting strings. */ - strcpy(etDialog.path, window->path); - strcpy(etDialog.filename, window->filename); + strcpy(etDialog.path, window->editorInfo->path); + strcpy(etDialog.filename, window->editorInfo->filename); #ifndef VMS strcpy(etDialog.viewTag, GetClearCaseViewTag() != NULL ? GetClearCaseViewTag() : @@ -1454,9 +1453,9 @@ GetPrefServerName() : "servername"); etDialog.isServer = IsServer; - etDialog.filenameSet = window->filenameSet; - etDialog.lockReasons = window->lockReasons; - etDialog.fileChanged = window->fileChanged; + etDialog.filenameSet = window->editorInfo->filenameSet; + etDialog.lockReasons = window->editorInfo->lockReasons; + etDialog.fileChanged = window->editorInfo->fileChanged; if (etDialog.window != window && etDialog.form) {