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

📄 searchandreplace.java

📁 用java 编写的源码开放的文本编辑器。有很多有用的特性
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
					repeat = true;				}				else					break loop;			}		}		catch(Exception e)		{			Log.log(Log.ERROR,SearchAndReplace.class,e);			Object[] args = { e.getMessage() };			if(args[0] == null)				args[0] = e.toString();			GUIUtilities.error(comp,"searcherror",args);		}		finally		{			view.hideWaitCursor();		}		return false;	} //}}}	//{{{ find() method	/**	 * 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	 */	public static boolean find(View view, Buffer buffer, int start)		throws Exception	{		return find(view,buffer,start,false,false);	} //}}}	//{{{ find() method	/**	 * 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(CharIndexed,	 * boolean,boolean,boolean,boolean)}.	 * @since jEdit 4.1pre7	 */	public static boolean find(View view, Buffer buffer, int start,		boolean firstTime, boolean reverse) throws Exception	{		SearchMatcher matcher = getSearchMatcher();		if(matcher == null)		{			view.getToolkit().beep();			return false;		}		Segment text = new Segment();		if(reverse)			buffer.getText(0,start,text);		else			buffer.getText(start,buffer.getLength() - start,text);		// the start and end flags will be wrong with reverse search enabled,		// but they are only used by the regexp matcher, which doesn't		// support reverse search yet.		//		// REMIND: fix flags when adding reverse regexp search.		int[] match = matcher.nextMatch(new CharIndexedSegment(text,reverse),			start == 0,true,firstTime,reverse);		if(match != null)		{			jEdit.commitTemporary(buffer);			view.setBuffer(buffer);			JEditTextArea textArea = view.getTextArea();			if(reverse)			{				textArea.setSelection(new Selection.Range(					start - match[1],					start - match[0]));				textArea.moveCaretPosition(start - match[1]);			}			else			{				textArea.setSelection(new Selection.Range(					start + match[0],					start + match[1]));				textArea.moveCaretPosition(start + match[1]);			}			return true;		}		else			return false;	} //}}}	//{{{ replace() method	/**	 * 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 = (replace != null			&& TextUtilities.getStringCase(replace)			== TextUtilities.LOWER_CASE);		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;			int retVal = 0;			for(int i = 0; i < selection.length; i++)			{				s = selection[i];				/* if an occurence occurs at the				beginning of the selection, the				selection start will get moved.				this sucks, so we hack to avoid it. */				int start = s.getStart();				if(s instanceof Selection.Range)				{					retVal += _replace(view,buffer,matcher,						s.getStart(),s.getEnd(),						smartCaseReplace);					textArea.removeFromSelection(s);					textArea.addToSelection(new Selection.Range(						start,s.getEnd()));				}				else if(s instanceof Selection.Rect)				{					for(int j = s.getStartLine(); j <= s.getEndLine(); j++)					{						retVal += _replace(view,buffer,matcher,							s.getStart(buffer,j),s.getEnd(buffer,j),							smartCaseReplace);					}					textArea.addToSelection(new Selection.Rect(						start,s.getEnd()));				}			}			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(retVal == 0)			{				view.getToolkit().beep();				return false;			}			return true;		}		catch(Exception e)		{			Log.log(Log.ERROR,SearchAndReplace.class,e);			Object[] args = { e.getMessage() };			if(args[0] == null)				args[0] = e.toString();			GUIUtilities.error(comp,"searcherror",args);		}		finally		{			buffer.endCompoundEdit();		}		return false;	} //}}}	//{{{ replace() method	/**	 * 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 = (replace != null			&& TextUtilities.getStringCase(replace)			== TextUtilities.LOWER_CASE);		try		{			buffer.beginCompoundEdit();			SearchMatcher matcher = getSearchMatcher();			if(matcher == null)				return false;			int retVal = 0;			retVal += _replace(view,buffer,matcher,start,end,				smartCaseReplace);			if(retVal != 0)				return true;		}		catch(Exception e)		{			Log.log(Log.ERROR,SearchAndReplace.class,e);			Object[] args = { e.getMessage() };			if(args[0] == null)				args[0] = e.toString();			GUIUtilities.error(comp,"searcherror",args);		}		finally		{			buffer.endCompoundEdit();		}		return false;	} //}}}	//{{{ replaceAll() method	/**	 * Replaces all occurances of the search string with the replacement	 * string.	 * @param view The view	 */	public static boolean replaceAll(View view)	{		// component that will parent any dialog boxes		Component comp = SearchDialog.getSearchDialog(view);		if(comp == null)			comp = view;		int fileCount = 0;		int occurCount = 0;		if(fileset.getFileCount(view) == 0)		{			GUIUtilities.error(comp,"empty-fileset",null);			return false;		}		record(view,"replaceAll(view)",true,true);		view.showWaitCursor();		boolean smartCaseReplace = (replace != null			&& TextUtilities.getStringCase(replace)			== TextUtilities.LOWER_CASE);		try		{			SearchMatcher matcher = getSearchMatcher();			if(matcher == null)				return false;			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;					jEdit.commitTemporary(buffer);				}			}		}		catch(Exception e)		{			Log.log(Log.ERROR,SearchAndReplace.class,e);			Object[] args = { e.getMessage() };			if(args[0] == null)				args[0] = e.toString();			GUIUtilities.error(comp,"searcherror",args);		}		finally		{			view.hideWaitCursor();		}		/* Don't do this when playing a macro, cos it's annoying */		if(!BeanShell.isScriptRunning())		{			Object[] args = { new Integer(occurCount),				new Integer(fileCount) };			view.getStatus().setMessageAndClear(jEdit.getProperty(				"view.status.replace-all",args));			if(occurCount == 0)				view.getToolkit().beep();		}		return (fileCount != 0);	} //}}}	//}}}	//{{{ load() method	/**	 * Loads search and replace state from the properties.	 */	public static void load()	{		search = jEdit.getProperty("search.find.value");		replace = jEdit.getProperty("search.replace.value");		ignoreCase = jEdit.getBooleanProperty("search.ignoreCase.toggle");		regexp = jEdit.getBooleanProperty("search.regexp.toggle");		beanshell = jEdit.getBooleanProperty("search.beanshell.toggle");		wrap = jEdit.getBooleanProperty("search.wrap.toggle");		fileset = new CurrentBufferSet();		// Tags plugin likes to call this method at times other than		// startup; so we need to fire a SearchSettingsChanged to		// notify the search bar and so on.		matcher = null;		EditBus.send(new SearchSettingsChanged(null));	} //}}}	//{{{ save() method	/**	 * Saves search and replace state to the properties.	 */	public static void save()	{		jEdit.setProperty("search.find.value",search);		jEdit.setProperty("search.replace.value",replace);		jEdit.setBooleanProperty("search.ignoreCase.toggle",ignoreCase);		jEdit.setBooleanProperty("search.regexp.toggle",regexp);		jEdit.setBooleanProperty("search.beanshell.toggle",beanshell);		jEdit.setBooleanProperty("search.wrap.toggle",wrap);	} //}}}	//{{{ Private members	//{{{ Instance variables	private static String search;	private static String replace;	private static boolean regexp;	private static boolean ignoreCase;	private static boolean reverse;	private static boolean beanshell;	private static boolean wrap;	private static SearchMatcher matcher;	private static SearchFileSet fileset;	//}}}	//{{{ record() method	private static void record(View view, String action,		boolean replaceAction, boolean recordFileSet)	{		Macros.Recorder recorder = view.getMacroRecorder();		if(recorder != null)		{			recorder.record("SearchAndReplace.setSearchString(\""				+ MiscUtilities.charsToEscapes(search) + "\");");			if(replaceAction)			{				recorder.record("SearchAndReplace.setReplaceString(\""					+ MiscUtilities.charsToEscapes(replace) + "\");");				recorder.record("SearchAndReplace.setBeanShellReplace("					+ beanshell + ");");			}			else			{				// only record this if doing a find next				recorder.record("SearchAndReplace.setAutoWrapAround("					+ wrap + ");");				recorder.record("SearchAndReplace.setReverseSearch("					+ reverse + ");");			}			recorder.record("SearchAndReplace.setIgnoreCase("				+ ignoreCase + ");");			recorder.record("SearchAndReplace.setRegexp("				+ regexp + ");");			if(recordFileSet)			{				recorder.record("SearchAndReplace.setSearchFileSet("					+ fileset.getCode() + ");");			}			recorder.record("SearchAndReplace." + action + ";");		}	} //}}}	//{{{ _replace() method	/**	 * Replaces all occurances of the search string with the replacement	 * string.	 * @param view The view	 * @param buffer The buffer	 * @param start The start offset	 * @param end The end offset	 * @param matcher The search matcher to use	 * @param smartCaseReplace See user's guide	 * @return The number of occurrences replaced	 */	private static int _replace(View view, Buffer buffer,		SearchMatcher matcher, int start, int end,		boolean smartCaseReplace)		throws Exception	{		int occurCount = 0;		boolean endOfLine = (buffer.getLineEndOffset(			buffer.getLineOfOffset(end)) - 1 == end);		Segment text = new Segment();		int offset = start;loop:		for(int counter = 0; ; counter++)		{			buffer.getText(offset,end - offset,text);			boolean startOfLine = (buffer.getLineStartOffset(				buffer.getLineOfOffset(offset)) == offset);			int[] occur = matcher.nextMatch(				new CharIndexedSegment(text,false),				startOfLine,endOfLine,counter == 0,				false);			if(occur == null)				break loop;			int _start = occur[0];			int _length = occur[1] - occur[0];			String found = new String(text.array,text.offset + _start,_length);			String subst = matcher.substitute(found);			if(smartCaseReplace && ignoreCase)			{				int strCase = TextUtilities.getStringCase(found);				if(strCase == TextUtilities.LOWER_CASE)					subst = subst.toLowerCase();				else if(strCase == TextUtilities.UPPER_CASE)					subst = subst.toUpperCase();				else if(strCase == TextUtilities.TITLE_CASE)					subst = TextUtilities.toTitleCase(subst);			}			if(subst != null)			{				buffer.remove(offset + _start,_length);				buffer.insert(offset + _start,subst);				occurCount++;				offset += _start + subst.length();				end += (subst.length() - found.length());			}			else				offset += _start + _length;		}		return occurCount;	} //}}}	//}}}}

⌨️ 快捷键说明

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