/**
   * 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;
  } // }}}
Example #2
0
 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");
 }
Example #3
0
 /**
  * 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();
 }
Example #4
0
 /**
  * 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;
 }
Example #6
0
  /**
   * 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);
  } // }}}
Example #7
0
  /**
   * 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;
  } // }}}
Example #8
0
 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;
 }
Example #9
0
  /**
   * 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;
  } // }}}
Example #11
0
  // {{{ 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();
  } // }}}
Example #12
0
  // {{{ 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;
  } // }}}
Example #14
0
 // {{{ 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);
  }
Example #16
0
  // {{{ 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);
  } // }}}
Example #18
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;
 } // }}}