/** * Replaces text in the specified range with the replacement string. * * @param view The view * @param buffer The buffer * @param start The start offset * @param end The end offset * @return True if the operation was successful, false otherwise */ public static boolean replace(View view, Buffer buffer, int start, int end) { if (!buffer.isEditable()) return false; // component that will parent any dialog boxes Component comp = SearchDialog.getSearchDialog(view); if (comp == null) comp = view; boolean smartCaseReplace = getSmartCaseReplace(); try { buffer.beginCompoundEdit(); SearchMatcher matcher = getSearchMatcher(); if (matcher == null) return false; initReplace(); int retVal = 0; retVal += _replace(view, buffer, matcher, start, end, smartCaseReplace); if (retVal != 0) return true; } catch (Exception e) { handleError(comp, e); } finally { buffer.endCompoundEdit(); } return false; } // }}}
public void update() { Buffer buffer = view.getBuffer(); String wrap = buffer.getStringProperty("wrap"); if (wrap.equals("none")) this.wrap.setText("-"); else if (wrap.equals("hard")) this.wrap.setText("H"); else if (wrap.equals("soft")) this.wrap.setText("S"); }
/** * insert text. * * <p>/** invokes an Action. * * @param view The view to run the script in. * @param node The node item * @param text The node content to be inserted. */ public static void insertText(View view, String text, XTreeNode node) { CommandQueue queue = new CommandQueue(); ScriptContext context = new ScriptContext(view, node, queue); Buffer buffer = view.getBuffer(); buffer.beginCompoundEdit(); InsertTextCommand.insertText(text, context); buffer.endCompoundEdit(); }
/** * runs an XInsertScript. * * @param view The view to run the script in. * @param script The node content to be run as a script. * @param node The node from where to start searching for variable substitutions */ public static void runXInsertScript(View view, String script, XTreeNode node) { CommandQueue queue = new CommandQueue(); Buffer buffer = view.getBuffer(); buffer.beginCompoundEdit(); try { char[] chars = script.toCharArray(); int start = 0; for (int i = start; i < chars.length; i++) { switch (chars[i]) { case '{': if (chars[i + 1] == '$' || chars[i + 1] == '@' || chars[i + 1] == '!' || chars[i + 1] == '%' || chars[i + 1] == '#' || chars[i + 1] == '*' || chars[i + 1] == '&') { // Log.log(Log.DEBUG, XScripter.class, "Adding insert text (\"" + text + "\") command // to queue"); // Insert the text between the last command and this one String text = script.substring(start, i); queue.add(new InsertTextCommand(text)); int j; inner: for (j = i; j < chars.length; j++) { if (chars[j] == '}' && chars[j - 1] != '\\') { // If end of command String cmd = script.substring(i + 1, j); cmd = Utilities.replace(cmd, "\\}", "}"); queue.add(getCommand(view, node, cmd)); // Add this command to queue break inner; } } i = j; // set parsing to continue at the end of the command start = j + 1; // set the start position for the next insert text command } break; } } String remainder = script.substring(start, script.length()); queue.add(new InsertTextCommand(remainder)); // Insert the text left over // Run commands in queue ScriptContext context = new ScriptContext(view, node, queue); queue.executeAll(context); } catch (StringIndexOutOfBoundsException e) { doError("Unknown", "Missing \"}\""); return; } catch (Exception e) { doError("Unknown", "Syntax error in script - Execution Aborted", e); return; } finally { buffer.endCompoundEdit(); } } // }}}
/** Build config for parsing. */ static ParserConfig forParsing(Buffer buffer, DefaultErrorSource errorSource) { ParserConfig config = new ParserConfig(buffer, errorSource); config.showErrors = Options.getBool("showErrors"); config.displayCodeParameters = Options.getBool("displayCodeParameters"); config.showDoccoHeadings = Options.getBool("showDoccoHeadings"); config.isCakefile = buffer.getName().equals("Cakefile"); return config; }
/** * Creates a new buffer I/O request. * * @param view The view * @param buffer The buffer * @param session The VFS session * @param vfs The VFS * @param path The path */ protected BufferIORequest(View view, Buffer buffer, Object session, VFS vfs, String path) { this.view = view; this.buffer = buffer; this.session = session; this.vfs = vfs; this.path = path; markersPath = Buffer.getMarkersPath(vfs, path); } // }}}
/** * Saves the specifies buffer. The default implementation posts an I/O request to the I/O thread. * * @param view The view * @param buffer The buffer * @param path The path */ public boolean save(View view, Buffer buffer, String path) { if ((getCapabilities() & WRITE_CAP) == 0) { VFSManager.error(view, path, "vfs.not-supported.save", new String[] {name}); return false; } Object session = createVFSSession(path, view); if (session == null) return false; /* When doing a 'save as', the path to save to (path) * will not be the same as the buffer's previous path * (buffer.getPath()). In that case, we want to create * a backup of the new path, even if the old path was * backed up as well (BACKED_UP property set) */ if (!path.equals(buffer.getPath())) buffer.unsetProperty(Buffer.BACKED_UP); VFSManager.runInWorkThread(new BufferSaveRequest(view, buffer, session, this, path)); return true; } // }}}
public static Buffer createFeatureBuffer() { View view = jEdit.getActiveView(); String parent = null; if (view != null) { Buffer buffer = view.getBuffer(); parent = buffer.getDirectory(); } if (parent == null) { parent = System.getProperty("user.home"); } VFS vfs = VFSManager.getVFSForPath(parent); if ((vfs.getCapabilities() & VFS.WRITE_CAP) == 0) { // cannot write on that VFS, creating untitled buffer in home directory parent = System.getProperty("user.home"); } Buffer buffer = jEdit.openTemporary(view, tempPath(), getNextFeatureTemp(), true, null); jEdit.commitTemporary(buffer); return buffer; }
/** * Loads the specified buffer. The default implementation posts an I/O request to the I/O thread. * * @param view The view * @param buffer The buffer * @param path The path */ public boolean load(View view, Buffer buffer, String path) { if ((getCapabilities() & READ_CAP) == 0) { VFSManager.error(view, path, "vfs.not-supported.load", new String[] {name}); return false; } Object session = createVFSSession(path, view); if (session == null) return false; if ((getCapabilities() & WRITE_CAP) == 0) buffer.setReadOnly(true); BufferIORequest request = new BufferLoadRequest(view, buffer, session, this, path); if (buffer.isTemporary()) // this makes HyperSearch much faster request.run(); else VFSManager.runInWorkThread(request); return true; } // }}}
/** * Finds the next instance of the search string in the specified buffer. * * @param view The view * @param buffer The buffer * @param start Location where to start the search * @param firstTime See {@link * SearchMatcher#nextMatch(CharSequence,boolean,boolean,boolean,boolean)}. * @since jEdit 4.1pre7 */ public static boolean find( View view, Buffer buffer, int start, boolean firstTime, boolean reverse) throws Exception { EditBus.send(new PositionChanging(view.getEditPane())); SearchMatcher matcher = getSearchMatcher(); if (matcher == null) { view.getToolkit().beep(); return false; } CharSequence text; boolean startOfLine; boolean endOfLine; if (reverse) { text = new ReverseCharSequence(buffer.getSegment(0, start)); startOfLine = true; endOfLine = (buffer.getLineEndOffset(buffer.getLineOfOffset(start)) - 1 == start); } else { text = buffer.getSegment(start, buffer.getLength() - start); startOfLine = (buffer.getLineStartOffset(buffer.getLineOfOffset(start)) == start); endOfLine = true; } String noWordSep = buffer.getStringProperty("noWordSep"); matcher.setNoWordSep(noWordSep); SearchMatcher.Match match = matcher.nextMatch(text, startOfLine, endOfLine, firstTime, reverse); if (match != null) { jEdit.commitTemporary(buffer); view.setBuffer(buffer, true); JEditTextArea textArea = view.getTextArea(); if (reverse) { textArea.setSelection(new Selection.Range(start - match.end, start - match.start)); // make sure end of match is visible textArea.scrollTo(start - match.start, false); textArea.moveCaretPosition(start - match.end); } else { textArea.setSelection(new Selection.Range(start + match.start, start + match.end)); textArea.moveCaretPosition(start + match.end); // make sure start of match is visible textArea.scrollTo(start + match.start, false); } return true; } else return false; } // }}}
// {{{ write() method protected void write(Buffer buffer, OutputStream out) throws IOException { String encodingName = buffer.getStringProperty(JEditBuffer.ENCODING); Encoding encoding = EncodingServer.getEncoding(encodingName); Writer writer = encoding.getTextWriter(new BufferedOutputStream(out, getByteIOBufferSize())); Segment lineSegment = new Segment(); String newline = buffer.getStringProperty(JEditBuffer.LINESEP); if (newline == null) newline = System.getProperty("line.separator"); final int bufferLineCount = buffer.getLineCount(); setMaximum(bufferLineCount / PROGRESS_INTERVAL); setValue(0); int i = 0; while (i < bufferLineCount) { buffer.getLineText(i, lineSegment); try { writer.write(lineSegment.array, lineSegment.offset, lineSegment.count); if (i < bufferLineCount - 1 || (jEdit.getBooleanProperty("stripTrailingEOL") && buffer.getBooleanProperty(Buffer.TRAILING_EOL))) { writer.write(newline); } } catch (CharacterCodingException e) { String message = getWriteEncodingErrorMessage( encodingName, encoding, lineSegment, i); IOException wrapping = new CharConversionException(message); wrapping.initCause(e); throw wrapping; } if (++i % PROGRESS_INTERVAL == 0) setValue(i / PROGRESS_INTERVAL); } writer.flush(); } // }}}
// {{{ print() method public static void print(final View view, final Buffer buffer, boolean selection) { job = getPrintJob(buffer.getPath()); boolean header = jEdit.getBooleanProperty("print.header"); boolean footer = jEdit.getBooleanProperty("print.footer"); boolean lineNumbers = jEdit.getBooleanProperty("print.lineNumbers"); boolean color = jEdit.getBooleanProperty("print.color"); Font font = jEdit.getFontProperty("print.font"); BufferPrintable printable = new BufferPrintable(job, format, view, buffer, font, header, footer, lineNumbers, color); job.setPrintable(printable); if (!job.printDialog(format)) return; savePrintSpec(); printable.print(); } // }}}
/** * Finds the next occurrence of the search string. * * @param view The view * @return True if the operation was successful, false otherwise */ public static boolean find(View view) { // component that will parent any dialog boxes Component comp = SearchDialog.getSearchDialog(view); if (comp == null || !comp.isShowing()) comp = view; String path = fileset.getNextFile(view, null); if (path == null) { GUIUtilities.error(comp, "empty-fileset", null); return false; } try { view.showWaitCursor(); SearchMatcher matcher = getSearchMatcher(); if (matcher == null) { view.getToolkit().beep(); return false; } record(view, "find(view)", false, true); boolean repeat = false; loop: for (; ; ) { while (path != null) { Buffer buffer = jEdit.openTemporary(view, null, path, false); /* this is stupid and misleading. * but 'path' is not used anywhere except * the above line, and if this is done * after the 'continue', then we will * either hang, or be forced to duplicate * it inside the buffer == null, or add * a 'finally' clause. you decide which one's * worse. */ if (reverse) { path = fileset.getPrevFile(view, path); } else { path = fileset.getNextFile(view, path); } if (buffer == null) continue loop; // Wait for the buffer to load if (!buffer.isLoaded()) VFSManager.waitForRequests(); int start; if (view.getBuffer() == buffer && !repeat) { JEditTextArea textArea = view.getTextArea(); Selection s = textArea.getSelectionAtOffset(textArea.getCaretPosition()); if (s == null) start = textArea.getCaretPosition(); else if (reverse) start = s.getStart(); else start = s.getEnd(); } else if (reverse) start = buffer.getLength(); else start = 0; if (find(view, buffer, start, repeat, reverse)) return true; } if (repeat) { if (!BeanShell.isScriptRunning()) { view.getStatus().setMessageAndClear(jEdit.getProperty("view.status.search-not-found")); view.getToolkit().beep(); } return false; } boolean restart; // if auto wrap is on, always restart search. // if auto wrap is off, and we're called from // a macro, stop search. If we're called // interactively, ask the user what to do. if (wrap) { if (!BeanShell.isScriptRunning()) { view.getStatus().setMessageAndClear(jEdit.getProperty("view.status.auto-wrap")); // beep if beep property set if (jEdit.getBooleanProperty("search.beepOnSearchAutoWrap")) { view.getToolkit().beep(); } } restart = true; } else if (BeanShell.isScriptRunning()) { restart = false; } else { Integer[] args = {Integer.valueOf(reverse ? 1 : 0)}; int result = GUIUtilities.confirm( comp, "keepsearching", args, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); restart = (result == JOptionPane.YES_OPTION); } if (restart) { // start search from beginning path = fileset.getFirstFile(view); repeat = true; } else break loop; } } catch (Exception e) { handleError(comp, e); } finally { view.hideWaitCursor(); } return false; } // }}}
// {{{ wantTwoStageSave() method private static boolean wantTwoStageSave(Buffer buffer) { return !buffer.getBooleanProperty("forbidTwoStageSave") && (buffer.getBooleanProperty("overwriteReadonly") || jEdit.getBooleanProperty("twoStageSave")); } // }}}
protected void getHaxeCompilerCompletions(View view, List<CompletionCandidate> candidates) { TextArea ta = view.getTextArea(); int dotPosition = ta.getCaretPosition(); if (!ta.getText(dotPosition - 1, 1).equals(".")) { return; } // If the caret is at a ".", use the Haxe compiler to provide completion hints Buffer buffer = view.getBuffer(); // Save the file if dirty if (buffer.isDirty()) { buffer.save(view, null, false, true); // Wait a bit to allow the save notifications to go through and not // bork the reload/popup try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } HaxeCompilerOutput output = HaXeSideKickPlugin.getHaxeBuildOutput(view.getEditPane(), dotPosition, true); trace(output); if (output == null || output.output == null || output.output.errors == null) { trace(" haxe build error, no completion candidates"); return; } String completionXMLString = output.output.errors.trim(); if (completionXMLString == null || completionXMLString.equals("") || !completionXMLString.startsWith("<")) { return; } List<CompletionCandidate> localCandidates = new ArrayList<CompletionCandidate>(); try { // Example see http://www.rgagnon.com/javadetails/java-0573.html DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); InputSource is = new InputSource(); is.setCharacterStream(new StringReader(completionXMLString)); Document doc = db.parse(is); NodeList insertions = doc.getElementsByTagName("i"); // iterate the insertions for (int i = 0; i < insertions.getLength(); i++) { Element element = (Element) insertions.item(i); if (element.getNodeName().equals("i")) { // Insertion String codeName = element.getAttribute("n"); String argString = ((Element) element.getElementsByTagName("t").item(0)).getTextContent(); String[] methodTokens = argString.split("->"); String returns = methodTokens[methodTokens.length - 1]; String docs = ((Element) element.getElementsByTagName("d").item(0)).getTextContent(); if (methodTokens.length == 1) { localCandidates.add(new CodeCompletionField(codeName, returns, docs)); } else { CodeCompletionMethod cc = new CodeCompletionMethod(codeName, returns, docs); if (methodTokens.length > 1 && !methodTokens[0].trim().equals("Void")) { List<String> args = new ArrayList<String>(methodTokens.length - 1); List<String> argsTypes = new ArrayList<String>(methodTokens.length - 1); for (int jj = 0; jj < methodTokens.length - 1; ++jj) { String[] argTokens = methodTokens[jj].split(":"); args.add(argTokens[0]); if (argTokens.length > 1) { argsTypes.add(argTokens[1]); } } cc.arguments = args; cc.argumentTypes = argsTypes; } localCandidates.add(cc); } } } trace("Number of code completions=" + localCandidates.size()); } catch (Exception e) { e.printStackTrace(); } Collections.sort(localCandidates); candidates.addAll(localCandidates); }
// {{{ run() method public void run() { /* if the VFS supports renaming files, we first * save to #<filename>#save#, then rename that * to <filename>, so that if the save fails, * data will not be lost. * * as of 4.1pre7 we now call vfs.getTwoStageSaveName() * instead of constructing the path directly * since some VFS's might not allow # in filenames. */ boolean vfsRenameCap = (vfs.getCapabilities() & VFS.RENAME_CAP) != 0; boolean wantTwoStage = wantTwoStageSave(buffer); boolean twoStageSave = vfsRenameCap && wantTwoStage; try { String[] args = {vfs.getFileName(path)}; setStatus(jEdit.getProperty("vfs.status.save", args)); // the entire save operation can be aborted... setAbortable(true); path = vfs._canonPath(session, path, view); if (!MiscUtilities.isURL(path)) path = MiscUtilities.resolveSymlinks(path); String savePath; if (twoStageSave) { savePath = vfs.getTwoStageSaveName(path); if (savePath == null) { throw new IOException("Can't get a temporary path for two-stage save: " + path); } } else { makeBackup(); savePath = path; } OutputStream out = vfs._createOutputStream(session, savePath, view); if (out == null) { buffer.setBooleanProperty(ERROR_OCCURRED, true); return; } try { // this must be after the stream is created or // we deadlock with SSHTools. buffer.readLock(); try { // Can't use buffer.getName() here because // it is not changed until the save is // complete if (path.endsWith(".gz")) buffer.setBooleanProperty(Buffer.GZIPPED, true); else if (buffer.getName().endsWith(".gz")) { // The path do not ends with gz. // The buffer name was .gz. // So it means it's blabla.txt.gz -> blabla.txt, I remove // the gz property buffer.setBooleanProperty(Buffer.GZIPPED, false); } if (buffer.getBooleanProperty(Buffer.GZIPPED)) out = new GZIPOutputStream(out); write(buffer, out); } finally { buffer.readUnlock(); } } finally { IOUtilities.closeQuietly(out); } if (twoStageSave) { makeBackup(); if (!vfs._rename(session, savePath, path, view)) throw new IOException("Rename failed: " + savePath); } if (!twoStageSave) VFSManager.sendVFSUpdate(vfs, path, true); } catch (FileNotFoundException e) { Log.log(Log.ERROR, this, "Unable to save buffer " + e); String[] pp = {e.getMessage()}; VFSManager.error(view, path, "ioerror.write-error", pp); buffer.setBooleanProperty(ERROR_OCCURRED, true); } catch (UnsupportedCharsetException e) { Log.log(Log.ERROR, this, e, e); String[] pp = {e.getCharsetName()}; VFSManager.error(view, path, "ioerror.unsupported-encoding-error", pp); buffer.setBooleanProperty(ERROR_OCCURRED, true); } catch (Exception e) { Log.log(Log.ERROR, this, e); String[] pp = {e.toString()}; VFSManager.error(view, path, "ioerror.write-error", pp); buffer.setBooleanProperty(ERROR_OCCURRED, true); } catch (WorkThread.Abort a) { buffer.setBooleanProperty(ERROR_OCCURRED, true); } finally { try { vfs._saveComplete(session, buffer, path, view); if (twoStageSave) { vfs._finishTwoStageSave(session, buffer, path, view); } // clean up left-over markers file if (!jEdit.getBooleanProperty("persistentMarkers")) vfs._delete(session, Buffer.getMarkersPath(vfs, path), view); vfs._endVFSSession(session, view); } catch (Exception e) { Log.log(Log.ERROR, this, e); String[] pp = {e.toString()}; VFSManager.error(view, path, "ioerror.write-error", pp); buffer.setBooleanProperty(ERROR_OCCURRED, true); } catch (WorkThread.Abort a) { buffer.setBooleanProperty(ERROR_OCCURRED, true); } } } // }}}
/** * Replaces all occurrences of the search string with the replacement string. * * @param view The view * @param dontOpenChangedFiles Whether to open changed files or to autosave them quietly * @return the number of modified files */ public static boolean replaceAll(View view, boolean dontOpenChangedFiles) { // component that will parent any dialog boxes Component comp = SearchDialog.getSearchDialog(view); if (comp == null) comp = view; if (fileset.getFileCount(view) == 0) { GUIUtilities.error(comp, "empty-fileset", null); return false; } record(view, "replaceAll(view)", true, true); view.showWaitCursor(); boolean smartCaseReplace = getSmartCaseReplace(); int fileCount = 0; int occurCount = 0; try { SearchMatcher matcher = getSearchMatcher(); if (matcher == null) return false; initReplace(); String path = fileset.getFirstFile(view); loop: while (path != null) { Buffer buffer = jEdit.openTemporary(view, null, path, false); /* this is stupid and misleading. * but 'path' is not used anywhere except * the above line, and if this is done * after the 'continue', then we will * either hang, or be forced to duplicate * it inside the buffer == null, or add * a 'finally' clause. you decide which one's * worse. */ path = fileset.getNextFile(view, path); if (buffer == null) continue loop; // Wait for buffer to finish loading if (buffer.isPerformingIO()) VFSManager.waitForRequests(); if (!buffer.isEditable()) continue loop; // Leave buffer in a consistent state if // an error occurs int retVal = 0; try { buffer.beginCompoundEdit(); retVal = _replace(view, buffer, matcher, 0, buffer.getLength(), smartCaseReplace); } finally { buffer.endCompoundEdit(); } if (retVal != 0) { fileCount++; occurCount += retVal; if (dontOpenChangedFiles) { buffer.save(null, null); } else { jEdit.commitTemporary(buffer); jEdit.getBufferSetManager().addBuffer(view, buffer); } } } } catch (Exception e) { handleError(comp, e); } finally { view.hideWaitCursor(); } /* Don't do this when playing a macro, cos it's annoying */ if (!BeanShell.isScriptRunning()) { Object[] args = {Integer.valueOf(occurCount), Integer.valueOf(fileCount)}; view.getStatus().setMessageAndClear(jEdit.getProperty("view.status.replace-all", args)); if (occurCount == 0) view.getToolkit().beep(); } return (fileCount != 0); } // }}}
// {{{ read() method protected SegmentBuffer read(Reader in, long length, boolean insert) throws IOException { /* we guess an initial size for the array */ IntegerArray endOffsets = new IntegerArray(Math.max(1, (int) (length / 50))); // only true if the file size is known boolean trackProgress = !buffer.isTemporary() && length != 0; if (trackProgress) { setMaximum(length); setValue(0); } // if the file size is not known, start with a resonable // default buffer size if (length == 0) length = IOBUFSIZE; SegmentBuffer seg = new SegmentBuffer((int) length + 1); char[] buf = new char[IOBUFSIZE]; /* Number of characters in 'buf' array. InputStream.read() doesn't always fill the array (eg, the file size is not a multiple of IOBUFSIZE, or it is a GZipped file, etc) */ int len; // True if a \n was read after a \r. Usually // means this is a DOS/Windows file boolean CRLF = false; // A \r was read, hence a MacOS file boolean CROnly = false; // Was the previous read character a \r? // If we read a \n and this is true, we assume // we have a DOS/Windows file boolean lastWasCR = false; // Number of lines read. Every 100 lines, we update the // progress bar int lineCount = 0; while ((len = in.read(buf, 0, buf.length)) != -1) { // Offset of previous line, relative to // the start of the I/O buffer (NOT // relative to the start of the document) int lastLine = 0; for (int i = 0; i < len; i++) { // Look for line endings. switch (buf[i]) { case '\r': // If we read a \r and // lastWasCR is also true, // it is probably a Mac file // (\r\r in stream) if (lastWasCR) { CROnly = true; CRLF = false; } // Otherwise set a flag, // so that \n knows that last // was a \r else { lastWasCR = true; } // Insert a line seg.append(buf, lastLine, i - lastLine); seg.append('\n'); endOffsets.add(seg.count); if (trackProgress && lineCount++ % PROGRESS_INTERVAL == 0) setValue(seg.count); // This is i+1 to take the // trailing \n into account lastLine = i + 1; break; case '\n': /* If lastWasCR is true, we just read a \r followed by a \n. We specify that this is a Windows file, but take no further action and just ignore the \r. */ if (lastWasCR) { CROnly = false; CRLF = true; lastWasCR = false; /* Bump lastLine so that the next line doesn't erronously pick up the \r */ lastLine = i + 1; } /* Otherwise, we found a \n that follows some other * character, hence we have a Unix file */ else { CROnly = false; CRLF = false; seg.append(buf, lastLine, i - lastLine); seg.append('\n'); endOffsets.add(seg.count); if (trackProgress && lineCount++ % PROGRESS_INTERVAL == 0) setValue(seg.count); lastLine = i + 1; } break; default: /* If we find some other character that follows a \r, so it is not a Windows file, and probably a Mac file */ if (lastWasCR) { CROnly = true; CRLF = false; lastWasCR = false; } break; } } if (trackProgress) setValue(seg.count); // Add remaining stuff from buffer seg.append(buf, lastLine, len - lastLine); } setAbortable(false); String lineSeparator; if (seg.count == 0) { // fix for "[ 865589 ] 0-byte files should open using // the default line seperator" lineSeparator = jEdit.getProperty("buffer.lineSeparator", System.getProperty("line.separator")); } else if (CRLF) lineSeparator = "\r\n"; else if (CROnly) lineSeparator = "\r"; else lineSeparator = "\n"; // Chop trailing newline and/or ^Z (if any) int bufferLength = seg.count; if (bufferLength != 0) { char ch = seg.array[bufferLength - 1]; if (ch == 0x1a /* DOS ^Z */) seg.count--; } buffer.setBooleanProperty(Buffer.TRAILING_EOL, false); if (bufferLength != 0 && jEdit.getBooleanProperty("stripTrailingEOL")) { char ch = seg.array[bufferLength - 1]; if (ch == '\n') { buffer.setBooleanProperty(Buffer.TRAILING_EOL, true); seg.count--; endOffsets.setSize(endOffsets.getSize() - 1); } } // add a line marker at the end for proper offset manager // operation endOffsets.add(seg.count + 1); // to avoid having to deal with read/write locks and such, // we insert the loaded data into the buffer in the // post-load cleanup runnable, which runs in the AWT thread. if (!insert) { buffer.setProperty(LOAD_DATA, seg); buffer.setProperty(END_OFFSETS, endOffsets); buffer.setProperty(NEW_PATH, path); if (lineSeparator != null) buffer.setProperty(JEditBuffer.LINESEP, lineSeparator); } // used in insert() return seg; } // }}}
/** * Replaces the current selection with the replacement string. * * @param view The view * @return True if the operation was successful, false otherwise */ public static boolean replace(View view) { // component that will parent any dialog boxes Component comp = SearchDialog.getSearchDialog(view); if (comp == null) comp = view; JEditTextArea textArea = view.getTextArea(); Buffer buffer = view.getBuffer(); if (!buffer.isEditable()) return false; boolean smartCaseReplace = getSmartCaseReplace(); Selection[] selection = textArea.getSelection(); if (selection.length == 0) { view.getToolkit().beep(); return false; } record(view, "replace(view)", true, false); // a little hack for reverse replace and find int caret = textArea.getCaretPosition(); Selection s = textArea.getSelectionAtOffset(caret); if (s != null) caret = s.getStart(); try { buffer.beginCompoundEdit(); SearchMatcher matcher = getSearchMatcher(); if (matcher == null) return false; initReplace(); int retVal = 0; for (int i = 0; i < selection.length; i++) { s = selection[i]; retVal += replaceInSelection(view, textArea, buffer, matcher, smartCaseReplace, s); } if (reverse) { // so that Replace and Find continues from // the right location textArea.moveCaretPosition(caret); } else { s = textArea.getSelectionAtOffset(textArea.getCaretPosition()); if (s != null) textArea.moveCaretPosition(s.getEnd()); } if (!BeanShell.isScriptRunning()) { Object[] args = {Integer.valueOf(retVal), Integer.valueOf(1)}; view.getStatus().setMessageAndClear(jEdit.getProperty("view.status.replace-all", args)); } if (retVal == 0) { view.getToolkit().beep(); return false; } return true; } catch (Exception e) { handleError(comp, e); } finally { buffer.endCompoundEdit(); } return false; } // }}}
/** Should be somewhere else... */ private static int getColumnOnOtherLine(Buffer buffer, int line, int col) { int returnValue = buffer.getOffsetOfVirtualColumn(line, col, null); if (returnValue == -1) return buffer.getLineEndOffset(line) - 1; else return buffer.getLineStartOffset(line) + returnValue; } // }}}