📄 buffer.java
字号:
* if only a copy should be saved to the specified filename * @since jEdit 2.6pre5 */ public boolean saveAs(View view, boolean rename) { String[] files = GUIUtilities.showVFSFileDialog(view,path, VFSBrowser.SAVE_DIALOG,false); // files[] should have length 1, since the dialog type is // SAVE_DIALOG if(files == null) return false; return save(view,files[0],rename); } /** * Saves this buffer to the specified path name, or the current path * name if it's null. * @param view The view * @param path The path name to save the buffer to, or null to use * the existing path */ public boolean save(View view, String path) { return save(view,path,true); } /** * Saves this buffer to the specified path name, or the current path * name if it's null. * @param view The view * @param path The path name to save the buffer to, or null to use * the existing path * @param rename True if the buffer's path should be changed, false * if only a copy should be saved to the specified filename * @since jEdit 2.6pre5 */ public boolean save(final View view, String path, final boolean rename) { if(isPerformingIO()) { GUIUtilities.error(view,"buffer-multiple-io",null); return false; } if(path == null && getFlag(NEW_FILE)) return saveAs(view,rename); if(path == null && file != null) { long newModTime = file.lastModified(); if(newModTime != modTime) { Object[] args = { this.path }; int result = GUIUtilities.confirm(view, "filechanged-save",args, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if(result != JOptionPane.YES_OPTION) return false; } } setFlag(IO,true); EditBus.send(new BufferUpdate(this,view,BufferUpdate.SAVING)); if(path == null) path = this.path; // can't call setPath() here because we don't want a failed // 'save as' to change the buffer's path, so obtain the VFS // instance 'manually' VFS vfs = VFSManager.getVFSForPath(path); if(!vfs.save(view,this,path)) { setFlag(IO,false); return false; } final String oldPath = this.path; if(rename) setPath(path); // Once save is complete, do a few other things VFSManager.runInAWTThread(new Runnable() { public void run() { // Saving a NEW_FILE will create a file on // disk, thus file system browsers must reload if(getFlag(NEW_FILE) || !getPath().equals(oldPath)) VFSManager.sendVFSUpdate(getVFS(),getPath(),true); setFlag(IO,false); if(rename) { // we do a write lock so that the // autosave, which grabs a read lock, // is not executed between the // deletion of the autosave file // and clearing of the dirty flag try { Buffer.this._writeLock(); if(autosaveFile != null) autosaveFile.delete(); setFlag(AUTOSAVE_DIRTY,false); setFlag(READ_ONLY,false); setFlag(NEW_FILE,false); setFlag(UNTITLED,false); setFlag(DIRTY,false); } finally { Buffer.this._writeUnlock(); } if(!getPath().equals(oldPath)) { jEdit.updatePosition(Buffer.this); setMode(); } if(file != null) modTime = file.lastModified(); EditBus.send(new BufferUpdate(Buffer.this, view,BufferUpdate.DIRTY_CHANGED)); } } }); return true; } // these are only public so that an inner class can access them! public void _writeLock() { writeLock(); } public void _writeUnlock() { writeUnlock(); } /** * Returns the last time jEdit modified the file on disk. */ public long getLastModified() { return modTime; } /** * Sets the last time jEdit modified the file on disk. * @param modTime The new modification time */ public void setLastModified(long modTime) { this.modTime = modTime; } /** * Check if the buffer has changed on disk. */ public void checkModTime(View view) { // don't do these checks while a save is in progress, // because for a moment newModTime will be greater than // oldModTime, due to the multithreading if(file == null || getFlag(NEW_FILE) || getFlag(IO)) return; boolean newReadOnly = (file.exists() && !file.canWrite()); if(newReadOnly != getFlag(READ_ONLY)) { setFlag(READ_ONLY,newReadOnly); EditBus.send(new BufferUpdate(this, view,BufferUpdate.DIRTY_CHANGED)); } if(!jEdit.getBooleanProperty("view.checkModStatus")) return; long oldModTime = modTime; long newModTime = file.lastModified(); if(newModTime != oldModTime) { modTime = newModTime; if(!file.exists()) { setFlag(NEW_FILE,true); EditBus.send(new BufferUpdate(this, view,BufferUpdate.DIRTY_CHANGED)); Object[] args = { path }; GUIUtilities.message(view,"filedeleted",args); return; } String prop = (isDirty() ? "filechanged-dirty" : "filechanged-focus"); Object[] args = { path }; int result = GUIUtilities.confirm(view, prop,args,JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if(result == JOptionPane.YES_OPTION) { view.getEditPane().saveCaretInfo(); load(view,true); } } } /** * Returns the virtual filesystem responsible for loading and * saving this buffer. */ public VFS getVFS() { return vfs; } /** * Returns the file for this buffer. This may be null if the buffer * is non-local. */ public final File getFile() { return file; } /** * Returns the autosave file for this buffer. This may be null if * the file is non-local. */ public final File getAutosaveFile() { return autosaveFile; } /** * Returns the name of this buffer. */ public final String getName() { return name; } /** * Returns the path name of this buffer. */ public final String getPath() { return path; } /** * Returns true if this buffer has been closed with * <code>jEdit.closeBuffer()</code>. */ public final boolean isClosed() { return getFlag(CLOSED); } /** * Returns true if the buffer is loaded. */ public final boolean isLoaded() { return !getFlag(LOADING); } /** * Returns true if the buffer is currently performing I/O. * @since jEdit 2.7pre1 */ public final boolean isPerformingIO() { return getFlag(LOADING) || getFlag(IO); } /** * @deprecated Call isPerformingIO() instead */ public final boolean isSaving() { return getFlag(IO); } /** * Returns true if this file doesn't exist on disk. */ public final boolean isNewFile() { return getFlag(NEW_FILE); } /** * Sets the new file flag. * @param newFile The new file flag */ public final void setNewFile(boolean newFile) { setFlag(NEW_FILE,newFile); } /** * Returns true if this file is 'untitled'. */ public final boolean isUntitled() { return getFlag(UNTITLED); } /** * Returns true if this file has changed since last save, false * otherwise. */ public final boolean isDirty() { return getFlag(DIRTY); } /** * Returns true if this file is read only, false otherwise. */ public final boolean isReadOnly() { return getFlag(READ_ONLY); } /** * Returns true if this file is editable, false otherwise. * @since jEdit 2.7pre1 */ public final boolean isEditable() { return !(getFlag(READ_ONLY) || getFlag(IO) || getFlag(LOADING)); } /** * Sets the read only flag. * @param readOnly The read only flag */ public final void setReadOnly(boolean readOnly) { setFlag(READ_ONLY,readOnly); } /** * Sets the `dirty' (changed since last save) flag of this buffer. */ public void setDirty(boolean d) { boolean old_d = getFlag(DIRTY); if(d) { if(getFlag(LOADING) || getFlag(READ_ONLY)) return; if(getFlag(DIRTY) && getFlag(AUTOSAVE_DIRTY)) return; setFlag(DIRTY,true); setFlag(AUTOSAVE_DIRTY,true); } else { setFlag(DIRTY,false); setFlag(AUTOSAVE_DIRTY,false); } if(d != old_d) { EditBus.send(new BufferUpdate(this,null, BufferUpdate.DIRTY_CHANGED)); } } /** * Returns if this is a temporary buffer. * @see jEdit#openTemporary(View,String,String,boolean,boolean) * @see jEdit#commitTemporary(Buffer) * @since jEdit 2.2pre7 */ public boolean isTemporary() { return getFlag(TEMPORARY); } /** * Returns this buffer's icon. * @since jEdit 2.6pre6 */ public Icon getIcon() { if(getFlag(DIRTY)) return GUIUtilities.DIRTY_BUFFER_ICON; else if(getFlag(READ_ONLY)) return GUIUtilities.READ_ONLY_BUFFER_ICON; else if(getFlag(NEW_FILE)) return GUIUtilities.NEW_BUFFER_ICON; else return GUIUtilities.NORMAL_BUFFER_ICON; } /** * Undoes the most recent edit. * * @since jEdit 2.7pre2 */ public void undo() { if(undo == null) return; if(!isEditable()) { Toolkit.getDefaultToolkit().beep(); return; } try { setFlag(UNDO_IN_PROGRESS,true); undo.undo(); } catch(CannotUndoException cu) { Log.log(Log.DEBUG,this,cu); Toolkit.getDefaultToolkit().beep(); return; } finally { setFlag(UNDO_IN_PROGRESS,false); } } /** * Redoes the most recently undone edit. Returns true if the redo was * successful. * * @since jEdit 2.7pre2 */ public void redo() { if(undo == null) return; if(!isEditable()) { Toolkit.getDefaultToolkit().beep(); return; } try { setFlag(UNDO_IN_PROGRESS,true); undo.redo(); } catch(CannotRedoException cr) { Log.log(Log.DEBUG,this,cr); Toolkit.getDefaultToolkit().beep(); return; } finally { setFlag(UNDO_IN_PROGRESS,false); } } /** * Adds an undoable edit to this document. This is non-trivial * mainly because the text area adds undoable edits every time * the caret is moved. First of all, undos are ignored while * an undo is already in progress. This is no problem with Swing * Document undos, but caret undos are fired all the time and * this needs to be done. Also, insignificant undos are ignored * if the redo queue is non-empty to stop something like a caret * move from flushing all redos. * @param edit The undoable edit * * @since jEdit 2.2pre1 */ public void addUndoableEdit(UndoableEdit edit) { if(undo == null || getFlag(UNDO_IN_PROGRESS) || getFlag(LOADING)) return; // Ignore insificant edits if the redo queue is non-empty. // This stops caret movement from killing redos. if(undo.canRedo() && !edit.isSignificant()) return; if(compoundEdit != null) { compoundEditNonEmpty = true; compoundEdit.addEdit(edit); } else undo.addEdit(edit); } /** * Starts a compound edit. All edits from now on until * <code>endCompoundEdit()</code> are called will be merged * into one. This can be used to make a complex operation * undoable in one step. Nested calls to * <code>beginCompoundEdit()</code> behave as expected, * requiring the same number of <code>endCompoundEdit()</code> * calls to end the edit. * @see #endCompoundEdit() * @see #undo() */ public void beginCompoundEdit() { if(getFlag(TEMPORARY)) return; compoundEditCount++; if(compoundEdit == null) { compoundEditNonEmpty = false; compoundEdit = new CompoundEdit(); } } /** * Ends a compound edit. All edits performed since * <code>beginCompoundEdit()</code> was called can now * be undone in one step by calling <code>undo()</code>. * @see #beginCompoundEdit() * @see #undo() */ public void endCompoundEdit() { if(getFlag(TEMPORARY)) return; if(compoundEditCount == 0) return; compoundEditCount--; if(compoundEditCount == 0) { compoundEdit.end(); if(compoundEditNonEmpty && compoundEdit.canUndo()) undo.addEdit(compoundEdit); compoundEdit = null; } } /** * Returns if a compound edit is currently active. * @since jEdit 3.1pre1 */ public boolean insideCompoundEdit() { return compoundEdit != null; } /** * Removes trailing whitespace from all lines in the specified list. * @param list The line numbers * @since jEdit 3.2pre1 */ public void removeTrailingWhiteSpace(int[] lines) { Element map = getDefaultRootElement(); try { beginCompoundEdit(); for(int i = 0; i < lines.length; i++) { int pos, lineStart, lineEnd, tail; Element lineElement = map.getElement(lines[i]); getText(lineElement.getStartOffset(), lineElement.getEndOffset() - lineElement.getStartOffset() - 1,seg); // blank line
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -