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

📄 searchandreplace.java

📁 用java 编写的源码开放的文本编辑器。有很多有用的特性
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * SearchAndReplace.java - Search and replace * :tabSize=8:indentSize=8:noTabs=false: * :folding=explicit:collapseFolds=1: * * Copyright (C) 1999, 2000, 2001, 2002 Slava Pestov * Portions copyright (C) 2001 Tom Locke * * 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.search;//{{{ Importsimport bsh.BshMethod;import java.awt.Component;import javax.swing.JOptionPane;import javax.swing.text.Segment;import org.gjt.sp.jedit.*;import org.gjt.sp.jedit.io.VFSManager;import org.gjt.sp.jedit.msg.SearchSettingsChanged;import org.gjt.sp.jedit.textarea.*;import org.gjt.sp.util.Log;//}}}/** * Class that implements regular expression and literal search within * jEdit buffers.<p> * * There are two main groups of methods in this class: * <ul> * <li>Property accessors - for changing search and replace settings.</li> * <li>Actions - for performing search and replace.</li> * </ul> * * The "HyperSearch" and "Keep dialog" features, as reflected in * checkbox options in the search dialog, are not handled from within * this class. If you wish to have these options set before the search dialog * appears, make a prior call to either or both of the following: * * <pre> jEdit.setBooleanProperty("search.hypersearch.toggle",true); * jEdit.setBooleanProperty("search.keepDialog.toggle",true);</pre> * * If you are not using the dialog to undertake a search or replace, you may * call any of the search and replace methods (including * {@link #hyperSearch(View)}) without concern for the value of these properties. * * @author Slava Pestov * @author John Gellene (API documentation) * @version $Id: SearchAndReplace.java,v 1.43 2003/02/09 05:16:57 spestov Exp $ */public class SearchAndReplace{	//{{{ Getters and setters	//{{{ setSearchString() method	/**	 * Sets the current search string.	 * @param search The new search string	 */	public static void setSearchString(String search)	{		if(search.equals(SearchAndReplace.search))			return;		SearchAndReplace.search = search;		matcher = null;		EditBus.send(new SearchSettingsChanged(null));	} //}}}	//{{{ getSearchString() method	/**	 * Returns the current search string.	 */	public static String getSearchString()	{		return search;	} //}}}	//{{{ setReplaceString() method	/**	 * Sets the current replacement string.	 * @param search The new replacement string	 */	public static void setReplaceString(String replace)	{		if(replace.equals(SearchAndReplace.replace))			return;		SearchAndReplace.replace = replace;		matcher = null;		EditBus.send(new SearchSettingsChanged(null));	} //}}}	//{{{ getReplaceString() method	/**	 * Returns the current replacement string.	 */	public static String getReplaceString()	{		return replace;	} //}}}	//{{{ setIgnoreCase() method	/**	 * Sets the ignore case flag.	 * @param ignoreCase True if searches should be case insensitive,	 * false otherwise	 */	public static void setIgnoreCase(boolean ignoreCase)	{		if(ignoreCase == SearchAndReplace.ignoreCase)			return;		SearchAndReplace.ignoreCase = ignoreCase;		matcher = null;		EditBus.send(new SearchSettingsChanged(null));	} //}}}	//{{{ getIgnoreCase() method	/**	 * Returns the state of the ignore case flag.	 * @return True if searches should be case insensitive,	 * false otherwise	 */	public static boolean getIgnoreCase()	{		return ignoreCase;	} //}}}	//{{{ setRegexp() method	/**	 * Sets the state of the regular expression flag.	 * @param regexp True if regular expression searches should be	 * performed	 */	public static void setRegexp(boolean regexp)	{		if(regexp == SearchAndReplace.regexp)			return;		SearchAndReplace.regexp = regexp;		if(regexp && reverse)			reverse = false;		matcher = null;		EditBus.send(new SearchSettingsChanged(null));	} //}}}	//{{{ getRegexp() method	/**	 * Returns the state of the regular expression flag.	 * @return True if regular expression searches should be performed	 */	public static boolean getRegexp()	{		return regexp;	} //}}}	//{{{ setReverseSearch() method	/**	 * Determines whether a reverse search will conducted from the current	 * position to the beginning of a buffer. Note that reverse search and	 * regular expression search is mutually exclusive; enabling one will	 * disable the other.	 * @param reverse True if searches should go backwards,	 * false otherwise	 */	public static void setReverseSearch(boolean reverse)	{		if(reverse == SearchAndReplace.reverse)			return;		SearchAndReplace.reverse = (regexp ? false : reverse);		matcher = null;		EditBus.send(new SearchSettingsChanged(null));	} //}}}	//{{{ getReverseSearch() method	/**	 * Returns the state of the reverse search flag.	 * @return True if searches should go backwards,	 * false otherwise	 */	public static boolean getReverseSearch()	{		return reverse;	} //}}}	//{{{ setBeanShellReplace() method	/**	 * Sets the state of the BeanShell replace flag.	 * @param regexp True if the replace string is a BeanShell expression	 * @since jEdit 3.2pre2	 */	public static void setBeanShellReplace(boolean beanshell)	{		if(beanshell == SearchAndReplace.beanshell)			return;		SearchAndReplace.beanshell = beanshell;		matcher = null;		EditBus.send(new SearchSettingsChanged(null));	} //}}}	//{{{ getBeanShellReplace() method	/**	 * Returns the state of the BeanShell replace flag.	 * @return True if the replace string is a BeanShell expression	 * @since jEdit 3.2pre2	 */	public static boolean getBeanShellReplace()	{		return beanshell;	} //}}}	//{{{ setAutoWrap() method	/**	 * Sets the state of the auto wrap around flag.	 * @param wrap If true, the 'continue search from start' dialog	 * will not be displayed	 * @since jEdit 3.2pre2	 */	public static void setAutoWrapAround(boolean wrap)	{		if(wrap == SearchAndReplace.wrap)			return;		SearchAndReplace.wrap = wrap;		EditBus.send(new SearchSettingsChanged(null));	} //}}}	//{{{ getAutoWrap() method	/**	 * Returns the state of the auto wrap around flag.	 * @param wrap If true, the 'continue search from start' dialog	 * will not be displayed	 * @since jEdit 3.2pre2	 */	public static boolean getAutoWrapAround()	{		return wrap;	} //}}}	//{{{ setSearchMatcher() method	/**	 * Sets a custom search string matcher. Note that calling	 * {@link #setSearchString(String)}, {@link #setReplaceString(String)},	 * {@link #setIgnoreCase(boolean)}, {@link #setRegexp(boolean)},	 * {@link #setReverseSearch(boolean)} or	 * {@link #setBeanShellReplace(boolean)} will reset the matcher to the	 * default.	 */	public static void setSearchMatcher(SearchMatcher matcher)	{		SearchAndReplace.matcher = matcher;		EditBus.send(new SearchSettingsChanged(null));	} //}}}	//{{{ getSearchMatcher() method	/**	 * Returns the current search string matcher.	 * @param reverseOK Replacement commands need a non-reversed matcher,	 * so they set this to false	 * @exception IllegalArgumentException if regular expression search	 * is enabled, the search string or replacement string is invalid	 * @since jEdit 4.1pre7	 */	public static SearchMatcher getSearchMatcher()		throws Exception	{		if(matcher != null)			return matcher;		if(search == null || "".equals(search))			return null;		// replace must not be null		String replace = (SearchAndReplace.replace == null ? "" : SearchAndReplace.replace);		BshMethod replaceMethod;		if(beanshell && replace.length() != 0)		{			replaceMethod = BeanShell.cacheBlock("replace","return ("				+ replace + ");",true);		}		else			replaceMethod = null;		if(regexp)			matcher = new RESearchMatcher(search,replace,ignoreCase,				beanshell,replaceMethod);		else		{			matcher = new BoyerMooreSearchMatcher(search,replace,				ignoreCase,beanshell,replaceMethod);		}		return matcher;	} //}}}	//{{{ setSearchFileSet() method	/**	 * Sets the current search file set.	 * @param fileset The file set to perform searches in	 * @see AllBufferSet	 * @see CurrentBufferSet	 * @see DirectoryListSet	 */	public static void setSearchFileSet(SearchFileSet fileset)	{		SearchAndReplace.fileset = fileset;		EditBus.send(new SearchSettingsChanged(null));	} //}}}	//{{{ getSearchFileSet() method	/**	 * Returns the current search file set.	 */	public static SearchFileSet getSearchFileSet()	{		return fileset;	} //}}}	//}}}	//{{{ Actions	//{{{ hyperSearch() method	/**	 * Performs a HyperSearch.	 * @param view The view	 * @since jEdit 2.7pre3	 */	public static boolean hyperSearch(View view)	{		return hyperSearch(view,false);	} //}}}	//{{{ hyperSearch() method	/**	 * Performs a HyperSearch.	 * @param view The view	 * @param selection If true, will only search in the current selection.	 * Note that the file set must be the current buffer file set for this	 * to work.	 * @since jEdit 4.0pre1	 */	public static boolean hyperSearch(View view, boolean selection)	{		// component that will parent any dialog boxes		Component comp = SearchDialog.getSearchDialog(view);		if(comp == null)			comp = view;		record(view,"hyperSearch(view," + selection + ")",false,			!selection);		view.getDockableWindowManager().addDockableWindow(			HyperSearchResults.NAME);		final HyperSearchResults results = (HyperSearchResults)			view.getDockableWindowManager()			.getDockable(HyperSearchResults.NAME);		results.searchStarted();		try		{			SearchMatcher matcher = getSearchMatcher();			if(matcher == null)			{				view.getToolkit().beep();				results.searchFailed();				return false;			}			Selection[] s;			if(selection)			{				s = view.getTextArea().getSelection();				if(s == null)				{					results.searchFailed();					return false;				}			}			else				s = null;			VFSManager.runInWorkThread(new HyperSearchRequest(view,				matcher,results,s));			return true;		}		catch(Exception e)		{			results.searchFailed();			Log.log(Log.ERROR,SearchAndReplace.class,e);			Object[] args = { e.getMessage() };			if(args[0] == null)				args[0] = e.toString();			GUIUtilities.error(comp,"searcherror",args);			return false;		}	} //}}}	//{{{ find() method	/**	 * Finds the next occurance 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 = view;		boolean repeat = false;		String path = fileset.getNextFile(view,null);		if(path == null)		{			GUIUtilities.error(comp,"empty-fileset",null);			return false;		}		try		{			SearchMatcher matcher = getSearchMatcher();			if(matcher == null)			{				view.getToolkit().beep();				return false;			}			record(view,"find(view)",false,true);			view.showWaitCursor();			boolean _reverse = reverse && fileset instanceof CurrentBufferSet;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. */					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(BeanShell.isScriptRunning())				{					restart = true;				}				else if(wrap)				{					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				{					Integer[] args = { new Integer(_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);

⌨️ 快捷键说明

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