📄 buffer.java
字号:
tmpVirtualMap[tmpMapLen++] = i; } else if(!fully && getFoldLevel(i) > initialFoldLevel) { // don't expand lines with higher fold // levels } else { // System.err.println("adding to map: " + i); tmpVirtualMap[tmpMapLen++] = i; delta++; info.visible = true; } } // I forgot to do this at first and it took me ages to // figure out int virtualLine; if(start > virtualLines[virtualLineCount - 1]) virtualLine = virtualLineCount; else virtualLine = physicalToVirtual(start); //System.err.println("virtual start is " + virtualLine // + ", physical start is " + start); //System.err.println("end=" + end + ",delta=" + delta); // update virtual -> physical map virtualLineCount += delta; //System.err.println("virtual line count is " + virtualLineCount); if(virtualLines.length <= virtualLineCount) { int[] virtualLinesN = new int[(virtualLineCount + 1) * 2]; System.arraycopy(virtualLines,0, virtualLinesN,0,virtualLines.length); virtualLines = virtualLinesN; } //System.err.println("copy from " + (virtualLine) // + " to " + (virtualLine + delta)); //System.err.println("foo: " + virtualLines[virtualLine]); System.arraycopy(virtualLines,virtualLine,virtualLines, virtualLine + delta,virtualLines.length - virtualLine - delta); for(int j = 0; j < tmpMapLen; j++) { //System.err.println((virtualLine + j) + " maps to " + tmpVirtualMap[j]); virtualLines[virtualLine + j] = tmpVirtualMap[j]; } fireFoldStructureChanged(); if(textArea != null) { int firstLine = textArea.getFirstLine(); int visibleLines = textArea.getVisibleLines(); if(virtualLine + delta >= firstLine + visibleLines && delta < visibleLines - 1) { textArea.setFirstLine(virtualLine + delta - visibleLines + 1); } } return true; } /** * This is intended to be called from actions.xml. * @since jEdit 3.1pre1 */ public void expandFolds(char digit) { if(digit < '1' || digit > '9') { Toolkit.getDefaultToolkit().beep(); return; } else expandFolds((int)(digit - '1') + 1); } /** * Expand all folds in the buffer up to a specified level. * @param level All folds less than this level will be expanded, * others will be collapsed. This is not the actual fold level; * it is multiplied by the indent size first * @since jEdit 3.1pre1 */ public void expandFolds(int level) { if(virtualLines.length <= lineCount) { int[] virtualLinesN = new int[(lineCount + 1) * 2]; System.arraycopy(virtualLines,0, virtualLinesN,0,virtualLines.length); virtualLines = virtualLinesN; } level = (level - 1) * getIndentSize() + 1; /* this ensures that the first line is always visible */ boolean seenVisibleLine = false; virtualLineCount = 0; for(int i = 0; i < lineCount; i++) { if(!seenVisibleLine || getFoldLevel(i) < level) { seenVisibleLine = true; lineInfo[i].visible = true; virtualLines[virtualLineCount++] = i; } else lineInfo[i].visible = false; } fireFoldStructureChanged(); } /** * Expand all folds in the specified document. * @since jEdit 3.1pre1 */ public void expandAllFolds() { if(virtualLines.length <= lineCount) { int[] virtualLinesN = new int[(lineCount + 1) * 2]; System.arraycopy(virtualLines,0, virtualLinesN,0,virtualLines.length); virtualLines = virtualLinesN; } virtualLineCount = lineCount; for(int i = 0; i < lineCount; i++) { virtualLines[i] = i; lineInfo[i].visible = true; } fireFoldStructureChanged(); } /** * Narrows the visible portion of the buffer to the specified * line range. * @param start The first line * @param end The last line * @since jEdit 3.1pre3 */ public void narrow(int start, int end) { virtualLineCount = end - start + 1; virtualLines = new int[virtualLineCount]; for(int i = 0; i < start; i++) lineInfo[i].visible = false; for(int i = start; i <= end; i++) { LineInfo info = lineInfo[i]; info.visible = true; virtualLines[i - start] = i; } for(int i = end + 1; i < lineCount; i++) lineInfo[i].visible = false; fireFoldStructureChanged(); } /** * Adds a fold listener. * @param listener The listener * @since jEdit 3.1pre1 */ public void addFoldListener(FoldListener l) { foldListeners.addElement(l); } /** * Removes a fold listener. * @param listener The listener * @since jEdit 3.1pre1 */ public void removeFoldListener(FoldListener l) { foldListeners.removeElement(l); } /** * Returns the number of physical lines in the buffer. * @since jEdit 3.1pre1 */ public int getLineCount() { return lineCount; } /** * Returns the number of virtual lines in the buffer. * @since jEdit 3.1pre1 */ public int getVirtualLineCount() { return virtualLineCount; } /** * Returns a vector of markers. * @since jEdit 3.2pre1 */ public final Vector getMarkers() { return markers; } /** * If a marker is set on the line of the position, it is removed. Otherwise * a new marker with the specified shortcut is added. * @param pos The position of the marker * @param shortcut The shortcut ('\0' if none) * @since jEdit 3.2pre5 */ public void addOrRemoveMarker(char shortcut, int pos) { Element map = getDefaultRootElement(); int line = map.getElementIndex(pos); if(getMarkerAtLine(line) != null) removeMarker(line); else addMarker(shortcut,pos); } /** * Adds a marker to this buffer. * @param pos The position of the marker * @param shortcut The shortcut ('\0' if none) * @since jEdit 3.2pre1 */ public void addMarker(char shortcut, int pos) { if(!getFlag(READ_ONLY) && jEdit.getBooleanProperty("persistentMarkers")) setDirty(true); Marker markerN = new Marker(this,shortcut,pos); boolean added = false; Element map = getDefaultRootElement(); int line = map.getElementIndex(pos); // don't sort markers while buffer is being loaded if(!getFlag(LOADING)) { markerN.createPosition(); for(int i = 0; i < markers.size(); i++) { Marker marker = (Marker)markers.elementAt(i); if(shortcut != '\0' && marker.getShortcut() == shortcut) marker.setShortcut('\0'); if(map.getElementIndex(marker.getPosition()) == line) { markers.removeElementAt(i); i--; } } for(int i = 0; i < markers.size(); i++) { Marker marker = (Marker)markers.elementAt(i); if(marker.getPosition() > pos) { markers.insertElementAt(markerN,i); added = true; break; } } } if(!added) markers.addElement(markerN); if(!getFlag(LOADING)) { EditBus.send(new BufferUpdate(this,null, BufferUpdate.MARKERS_CHANGED)); } } /** * Returns the first marker at the specified line. * @param line The line number * @since jEdit 3.2pre2 */ public Marker getMarkerAtLine(int line) { Element map = getDefaultRootElement(); for(int i = 0; i < markers.size(); i++) { Marker marker = (Marker)markers.elementAt(i); if(map.getElementIndex(marker.getPosition()) == line) return marker; } return null; } /** * Removes all markers at the specified line. * @param line The line number * @since jEdit 3.2pre2 */ public void removeMarker(int line) { Element map = getDefaultRootElement(); for(int i = 0; i < markers.size(); i++) { Marker marker = (Marker)markers.elementAt(i); if(map.getElementIndex(marker.getPosition()) == line) { if(!getFlag(READ_ONLY) && jEdit.getBooleanProperty("persistentMarkers")) setDirty(true); marker.removePosition(); markers.removeElementAt(i); i--; } } EditBus.send(new BufferUpdate(this,null, BufferUpdate.MARKERS_CHANGED)); } /** * Removes all defined markers. * @since jEdit 2.6pre1 */ public void removeAllMarkers() { if(!getFlag(READ_ONLY) && jEdit.getBooleanProperty("persistentMarkers")) setDirty(true); for(int i = 0; i < markers.size(); i++) ((Marker)markers.elementAt(i)).removePosition(); markers.removeAllElements(); EditBus.send(new BufferUpdate(this,null, BufferUpdate.MARKERS_CHANGED)); } /** * Returns the marker with the specified shortcut. * @param shortcut The shortcut * @since jEdit 3.2pre2 */ public Marker getMarker(char shortcut) { Enumeration enum = markers.elements(); while(enum.hasMoreElements()) { Marker marker = (Marker)enum.nextElement(); if(marker.getShortcut() == shortcut) return marker; } return null; } /** * Returns the next buffer in the list. */ public final Buffer getNext() { return next; } /** * Returns the previous buffer in the list. */ public final Buffer getPrev() { return prev; } /** * Returns the position of this buffer in the buffer list. */ public final int getIndex() { int count = 0; Buffer buffer = prev; for(;;) { if(buffer == null) break; count++; buffer = buffer.prev; } return count; } /** * Returns a string representation of this buffer. * This simply returns the path name. */ public String toString() { return name + " (" + vfs.getParentOfPath(path) + ")"; } public void handleMessage(EBMessage msg) { if(msg instanceof PropertiesChanged) propertiesChanged(); } // package-private members Buffer prev; Buffer next; Buffer(View view, String path, boolean newFile, boolean temp, Hashtable props) { lineCount = 1; lineInfo = new LineInfo[1]; lineInfo[0] = new LineInfo(); lineInfo[0].visible = true; virtualLineCount = 1; virtualLines = new int[1]; foldListeners = new Vector(); seg = new Segment(); lastTokenizedLine = -1; setDocumentProperties(new BufferProps()); clearProperties(); setFlag(TEMPORARY,temp); markers = new Vector(); addUndoableEditListener(new UndoHandler()); Enumeration keys = props.keys(); Enumeration values = props.elements(); while(keys.hasMoreElements()) { putProperty(keys.nextElement(),values.nextElement()); } Mode defaultMode = jEdit.getMode(jEdit.getProperty("buffer.defaultMode")); if(defaultMode == null) defaultMode = jEdit.getMode("text"); setMode(defaultMode); setPath(path); /* Magic: UNTITLED is only set if newFile param to * constructor is set, NEW_FILE is also set if file * doesn't exist on disk. * * This is so that we can tell apart files created * with jEdit.newFile(), and those that just don't * exist on disk. * * Why do we need to tell the difference between the * two? jEdit.addBufferToList() checks if the only * opened buffer is an untitled buffer, and if so, * replaces it with the buffer to add. We don't want * this behavior to occur with files that don't * exist on disk; only untitled ones. */ setFlag(UNTITLED,newFile); if(file != null) newFile |= !file.exists(); if(!temp) EditBus.addToBus(Buffer.this); setFlag(NEW_FILE,newFile); } void commitTemporary() { setFlag(TEMPORARY,false); EditBus.addToBus(this); } void close() { setFlag(CLOSED,true); if(autosaveFile != null) autosaveFile.delete(); EditBus.removeFromBus(this); } // protected members /** * We overwrite this method to update the line info array * state immediately so that any event listeners get a * consistent token marker. */ protected void fireInsertUpdate(DocumentEvent evt) { DocumentEvent.ElementChange ch = evt.getChange( getDefaultRootElement()); if(ch != null) { int index = ch.getIndex(); int len = ch.getChildrenAdded().length - ch.getChildrenRemoved().length; addLinesToMap(ch.getIndex() + 1,len); linesChanged(index,lineCount - index); index += (len + 1); } else { linesChanged(getDefaultRootElement() .getElementIndex(evt.getOffset()),1); } super.fireInsertUpdate(evt); setDirty(true); } /** * We overwrite this method to update the line info array * state immediately so that any event listeners get a * consistent token marker. */ protected void fireRemoveUpdate(DocumentEvent evt) { DocumentEvent.ElementChange ch = evt.getChange( getDefaultRootElement()); if(ch != null) { int index = ch.getIndex(); int len = ch.getChildrenRemoved().length - ch.getChildrenAdded().length; removeLinesFromMap(index,len); linesChanged(index,lineCount - index); } else { linesChanged(getDefaultRootElement() .getElementIndex(evt.getOffset()),1); } super.fireRemoveUpdate(evt); setDirty(true); } // private members private void setFlag(int flag, boolean value) { if(value) flags |= (1 << flag); else flags &= ~(1 << flag); } private boolean getFlag(int flag) { int mask = (1 << flag); return (flags & mask) == mask; } private static final int CLOSED = 0; private static final int LOADING = 1; private static final int IO = 2; private static final int NEW_FILE = 3; private static final int UNTITLED = 4; private static final int AUTOSAVE_DIRTY = 5; privat
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -