⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 offsetmanager.java

📁 用java 编写的源码开放的文本编辑器。有很多有用的特性
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * OffsetManager.java - Manages line info, line start offsets, positions * :tabSize=8:indentSize=8:noTabs=false: * :folding=explicit:collapseFolds=1: * * Copyright (C) 2001, 2002 Slava Pestov * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */package org.gjt.sp.jedit.buffer;//{{{ Importsimport javax.swing.text.*;import org.gjt.sp.jedit.syntax.*;import org.gjt.sp.jedit.Buffer;import org.gjt.sp.util.IntegerArray;import org.gjt.sp.util.Log;//}}}/** * A class internal to jEdit's document model. You should not use it * directly. To improve performance, none of the methods in this class * check for out of bounds access, nor are they thread-safe. The * <code>Buffer</code> class, through which these methods must be * called through, implements such protection. * * @author Slava Pestov * @version $Id: OffsetManager.java,v 1.33 2003/02/23 04:05:21 spestov Exp $ * @since jEdit 4.0pre1 */public class OffsetManager{	//{{{ OffsetManager constructor	public OffsetManager(Buffer buffer)	{		this.buffer = buffer;		lineInfo = new long[1];		// make first line visible by default		lineInfo[0] = 1L | (0xffL << VISIBLE_SHIFT);		lineContext = new TokenMarker.LineContext[1];		lineCount = 1;		positions = new PosBottomHalf[100];		virtualLineCounts = new int[8];		for(int i = 0; i < 8; i++)			virtualLineCounts[i] = 1;		gapLine = -1;	} //}}}	//{{{ getLineCount() method	public final int getLineCount()	{		return lineCount;	} //}}}	//{{{ getVirtualLineCount() method	public final int getVirtualLineCount(int index)	{		return virtualLineCounts[index];	} //}}}	//{{{ setVirtualLineCount() method	public final void setVirtualLineCount(int index, int lineCount)	{		virtualLineCounts[index] = lineCount;	} //}}}	//{{{ getLineOfOffset() method	public int getLineOfOffset(int offset)	{		int start = 0;		int end = lineCount - 1;		for(;;)		{			switch(end - start)			{			case 0:				if(getLineEndOffset(start) <= offset)					return start + 1;				else					return start;			case 1:				if(getLineEndOffset(start) <= offset)				{					if(getLineEndOffset(end) <= offset)						return end + 1;					else						return end;				}				else					return start;			default:				int pivot = (end + start) / 2;				int value = getLineEndOffset(pivot);				if(value == offset)					return pivot + 1;				else if(value < offset)					start = pivot + 1;				else					end = pivot - 1;				break;			}		}	} //}}}	//{{{ getLineEndOffset() method	public final int getLineEndOffset(int line)	{		int end = (int)(lineInfo[line] & END_MASK);		if(gapLine != -1 && line >= gapLine)			return end + gapWidth;		else			return end;	} //}}}	//{{{ isFoldLevelValid() method	public final boolean isFoldLevelValid(int line)	{		if(gapLine != -1 && line >= gapLine)			return false;		return (lineInfo[line] & FOLD_LEVEL_VALID_MASK) != 0;	} //}}}	//{{{ getFoldLevel() method	public final int getFoldLevel(int line)	{		return (int)((lineInfo[line] & FOLD_LEVEL_MASK)			>> FOLD_LEVEL_SHIFT);	} //}}}	//{{{ setFoldLevel() method	// Also sets 'fold level valid' flag	public final void setFoldLevel(int line, int level)	{		if(gapLine != -1 && line >= gapLine)			moveGap(line + 1,0,"setFoldLevel");		lineInfo[line] = ((lineInfo[line] & ~FOLD_LEVEL_MASK)			| ((long)level << FOLD_LEVEL_SHIFT)			| FOLD_LEVEL_VALID_MASK);	} //}}}	//{{{ isLineVisible() method	public final boolean isLineVisible(int line, int index)	{		long mask = 1L << (index + VISIBLE_SHIFT);		return (lineInfo[line] & mask) != 0;	} //}}}	//{{{ setLineVisible() method	public final void setLineVisible(int line, int index, boolean visible)	{		long mask = 1L << (index + VISIBLE_SHIFT);		if(visible)			lineInfo[line] = (lineInfo[line] | mask);		else			lineInfo[line] = (lineInfo[line] & ~mask);	} //}}}	/* the next two methods are not used!	//{{{ getScreenLineCount() method	public final int getScreenLineCount(int line)	{		return (int)((lineInfo[line] & SCREEN_LINES_MASK)			>> SCREEN_LINES_SHIFT);	} //}}}	//{{{ setScreenLineCount() method	public final void setScreenLineCount(int line, int count)	{		lineInfo[line] = ((lineInfo[line] & ~SCREEN_LINES_MASK)			| ((long)count << SCREEN_LINES_SHIFT));	} //}}}	*/	//{{{ isLineContextValid() method	public final boolean isLineContextValid(int line)	{		if(gapLine != -1 && line >= gapLine)			return false;		return (lineInfo[line] & CONTEXT_VALID_MASK) != 0;	} //}}}	//{{{ getLineContext() method	public final TokenMarker.LineContext getLineContext(int line)	{		return lineContext[line];	} //}}}	//{{{ setLineContext() method	// Also sets 'context valid' to true	public final void setLineContext(int line, TokenMarker.LineContext context)	{		if(gapLine != -1 && line >= gapLine)			moveGap(line + 1,0,"setLineContext");		lineContext[line] = context;		lineInfo[line] |= CONTEXT_VALID_MASK;	} //}}}	//{{{ createPosition() method	// note: Buffer.createPosition() grabs a read lock, so the buffer	// will not change during this method. however, if two stops call	// it, there can be contention issues unless this method is	// synchronized.	// I could make Buffer.createPosition() grab a write lock, but then	// it would be necessary to implement grabbing write locks within	// read locks, since HyperSearch for example does everything inside	// a read lock.	public synchronized Position createPosition(int offset)	{		PosBottomHalf bh = null;		for(int i = 0; i < positionCount; i++)		{			PosBottomHalf _bh = positions[i];			if(_bh.offset == offset)			{				bh = _bh;				break;			}			else if(_bh.offset > offset)			{				bh = new PosBottomHalf(offset);				growPositionArray();				System.arraycopy(positions,i,positions,i+1,					positionCount - i);				positionCount++;				positions[i] = bh;				break;			}		}		if(bh == null)		{			bh = new PosBottomHalf(offset);			growPositionArray();			positions[positionCount++] = bh;		}		return new PosTopHalf(bh);	} //}}}	//{{{ expandFolds() method	/**	 * Like <code>FoldVisibilityManager.expandFolds()</code>, but does	 * it for all fold visibility managers viewing this buffer. Should	 * only be called after loading.	 */	public void expandFolds(int foldLevel)	{		int newVirtualLineCount = 0;		if(foldLevel == 0)		{			newVirtualLineCount = lineCount;			for(int i = 0; i < lineCount; i++)				lineInfo[i] |= VISIBLE_MASK;		}		else		{			foldLevel = (foldLevel - 1) * buffer.getIndentSize() + 1;			/* this ensures that the first line is always visible */			boolean seenVisibleLine = false;			for(int i = 0; i < lineCount; i++)			{				if(!seenVisibleLine || buffer.getFoldLevel(i) < foldLevel)				{					seenVisibleLine = true;					lineInfo[i] |= VISIBLE_MASK;					newVirtualLineCount++;				}				else					lineInfo[i] &= ~VISIBLE_MASK;			}		}		for(int i = 0; i < virtualLineCounts.length; i++)		{			virtualLineCounts[i] = newVirtualLineCount;		}	} //}}}	//{{{ contentInserted() method	public void contentInserted(int startLine, int offset,		int numLines, int length, IntegerArray endOffsets)	{		int endLine = startLine + numLines;		//{{{ Update line info and line context arrays		if(numLines > 0)		{			moveGap(-1,0,"contentInserted");			lineCount += numLines;			if(lineInfo.length <= lineCount)			{				long[] lineInfoN = new long[(lineCount + 1) * 2];				System.arraycopy(lineInfo,0,lineInfoN,0,						 lineInfo.length);				lineInfo = lineInfoN;				TokenMarker.LineContext[] lineContextN					= new TokenMarker.LineContext[(lineCount + 1) * 2];				System.arraycopy(lineContext,0,lineContextN,0,						 lineContext.length);				lineContext = lineContextN;			}			System.arraycopy(lineInfo,startLine,lineInfo,				endLine,lineCount - endLine);			System.arraycopy(lineContext,startLine,lineContext,				endLine,lineCount - endLine);			//{{{ Find fold start of this line			int foldLevel = buffer.getFoldLevel(startLine);			long visible = (0xffL << VISIBLE_SHIFT);			if(startLine != 0)			{				for(int i = startLine; i > 0; i--)				{					if(/* buffer.isFoldStart(i - 1)						&& */ buffer.getFoldLevel(i) <= foldLevel)					{						visible = (lineInfo[i] & VISIBLE_MASK);						break;					}				}			} //}}}			for(int i = 0; i < numLines; i++)			{				// need the line end offset to be in place				// for following fold level calculations				lineInfo[startLine + i] = (offset					+ endOffsets.get(i) + 1)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -