标签:fse sample arraylist elements compile gradle delete htm seq
A virtual file com.intellij.openapi.vfs.VirtualFile is the IntelliJ Platform’s representation of a file in a file system (VFS). Most commonly, a virtual file is a file in your local file system. However, the IntelliJ Platform supports multiple pluggable file system implementations, so virtual files can also represent classes in a JAR file, old revisions of files loaded from a version control repository, and so on.
The VFS level deals only with binary content. You can get or set the contents of a VirtualFile
as a stream of bytes, but concepts like encodings and line separators are handled on higher system levels.
e.getData(PlatformDataKeys.VIRTUAL_FILE)
. If you are interested in multiple selection, you can also use e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY)
.LocalFileSystem.getInstance().findFileByIoFile()
psiFile.getVirtualFile()
(may return null if the PSI file exists only in memory)FileDocumentManager.getInstance().getFile()
Typical file operations are available, such as traverse the file system, get file contents, rename, move, or delete. Recursive iteration should be performed using VfsUtilCore.iterateChildrenRecursively
to prevent endless loops caused by recursive symlinks.
The VFS is built incrementally, by scanning the file system up and down starting from the project root. New files appearing in the file system are detected by VFS refreshes. A refresh operation can be initiated programmatically using (VirtualFileManager.getInstance().refresh()
or VirtualFile.refresh()
). VFS refreshes are also triggered whenever file system watchers receive file system change notifications (available on the Windows and Mac operating systems).
As a plugin developer, you may want to invoke a VFS refresh if you need to access a file that has just been created by an external tool through the IntelliJ Platform APIs.
A particular file on disk is represented by equal VirtualFile
instances for the entire lifetime of the IDEA process. There may be several instances corresponding to the same file, and they can be garbage-collected. The file is aUserDataHolder
, and the user data is shared between those equal instances. If a file is deleted, its corresponding VirtualFile instance becomes invalid (the isValid()
method returns false
and operations cause exceptions).
Usually you don’t. As a rule, files are created either through the PSI API or through the regular java.io.File API.
If you do need to create a file through VFS, you can use the VirtualFile.createChildData()
method to create aVirtualFile
instance and the VirtualFile.setBinaryContent()
method to write some data to the file.
The VirtualFileManager.addVirtualFileListener()
method allows you to receive notifications about all changes in the VFS.
To provide an alternative file system implementation (for example, an FTP file system), implement the VirtualFileSystemclass (most likely you’ll also need to implement VirtualFile
), and register your implementation as an application component.
To hook into operations performed in the local file system (for example, if you are developing a version control system integration that needs custom rename/move handling), implement the LocalFileOperationsHandler interface and register it through theLocalFileSystem.registerAuxiliaryFileOperationsHandler
method.
See IntelliJ Platform Virtual File System for a detailed description of the VFS architecture and usage guidelines.
A document is an editable sequence of Unicode characters, which typically corresponds to the text contents of a virtual file. Line breaks in a document are always normalized to \n
. The IntelliJ Platform handles encoding and line break conversions when loading and saving documents transparently.
e.getData(PlatformDataKeys.EDITOR).getDocument()
FileDocumentManager.getDocument()
. This call forces the document content to be loaded from disk if it wasn’t loaded previously; if you’re only interested in open documents or documents which may have been modified, use FileDocumentManager.getCachedDocument()
instead.PsiDocumentManager.getInstance().getDocument()
orPsiDocumentManager.getInstance().getCachedDocument()
You may perform any operations that access or modify the file contents on “plain text” level (as a sequence of characters, not as a tree of Java elements).
Document instances are created when some operation needs to access the text contents of a file (in particular, this is needed to build the PSI for a file). Also, document instances not linked to any virtual files can be created temporarily, for example, to represent the contents of a text editor field in a dialog.
Document instances are weakly referenced from VirtualFile
instances. Thus, an unmodified Document
instance can be garbage-collected if it isn’t referenced by anyone, and a new instance will be created if the document contents is accessed again later. Storing Document
references in long-term data structures of your plugin will cause memory leaks.
If you need to create a new file on disk, you don’t create a Document
: you create a PSI file and then get its Document
. If you need to create a Document
instance which isn’t bound to anything, you can use EditorFactory.createDocument
.
Document.addDocumentListener
allows you to receive notifications about changes in a particular Document
instance.EditorFactory.getEventMulticaster().addDocumentListener
allows you to receive notifications about changes in all open documents.FileDocumentManager.addFileDocumentManagerListener
allows you to receive notifications when any Document
is saved or reloaded from disk.The general read/write action rules are in effect. In addition to that, any operations which modify the contents of the document must be wrapped in a command (CommandProcessor.getInstance().executeCommand()
). executeCommand()
calls can be nested, and the outermost executeCommand
call is added to the undo stack. If multiple documents are modified within a command, undoing this command will by default show a confirmation dialog to the user.
If the file corresponding to a Document
is read-only (for example, not checked out from the version control system), document modifications will fail. Thus, before modifying the Document
, it is necessary to callReadonlyStatusHandler.getInstance(project).ensureFilesWritable()
to check out the file if necessary.
All text strings passed to Document
modification methods (setText
, insertString
, replaceString
) must use only \n as line separators.
A PSI (Program Structure Interface) file is the root of a structure representing the contents of a file as a hierarchy of elements in a particular programming language.
The PsiFile class is the common base class for all PSI files, while files in a specific language are usually represented by its subclasses. For example, the PsiJavaFile class represents a Java file, and the XmlFile class represents an XML file.
Unlike VirtualFile
and Document
, which have application scope (even if multiple projects are open, each file is represented by the same VirtualFile
instance), PSI has project scope (the same file is represented by multiplePsiFile
instances if the file belongs to multiple projects open at the same time).
e.getData(LangDataKeys.PSI_FILE)
.PsiManager.getInstance(project).findFile()
PsiDocumentManager.getInstance(project).getPsiFile()
psiElement.getContainingFile()
FilenameIndex.getFilesByName(project, name, scope)
Most interesting modification operations are performed on the level of individual PSI elements, not files as a whole.
To iterate over the elements in a file, use psiFile.accept(new PsiRecursiveElementWalkingVisitor()...);
As PSI is language-dependent, PSI files are created through the Language object, by using theLanguageParserDefinitions.INSTANCE.forLanguage(language).createFile(fileViewProvider)
method.
Like documents, PSI files are created on demand when the PSI is accessed for a particular file.
Like documents, PSI files are weakly referenced from the corresponding VirtualFile
instances and can be garbage-collected if not referenced by anyone.
The PsiFileFactory
.getInstance(project).createFileFromText()
method creates an in-memory PSI file with the specified contents.
To save the PSI file to disk, use the PsiDirectory
.add()
method.
PsiManager.getInstance(project).addPsiTreeChangeListener()
allows you to receive notifications about all changes to the PSI tree of a project.
PSI can be extended to support additional languages through custom language plugins. For more details on developing custom language plugins, see the Custom Language Support reference guide.
Any changes done to the content of PSI files are reflected in documents, so all rules for working with documents (read/write actions, commands, read-only status handling) are in effect.
A file view provider (see the FileViewProvider class) was introduced in IntelliJ IDEA 6.0. Its main purpose is to manage access to multiple PSI trees within a single file.
For example, a JSPX page has a separate PSI tree for the Java code in it (PsiJavaFile
), a separate tree for the XML code (XmlFile
), and a separate tree for JSP as a whole JspFile).
Each of the PSI trees covers the entire contents of the file, and contains special “outer language elements” in the places where contents in a different language can be found.
A FileViewProvider
instance corresponds to a single VirtualFile
, a single Document
, and can be used to retrieve multiple PsiFile
instances.
PsiManager.getInstance(project).findViewProvider()
psiFile.getViewProvider()
fileViewProvider.getLanguages()
fileViewProvider.getPsi(language)
, where the language
parameter can take values of the Language type defined in StdLanguages class. For example, to get the PSI tree for XML, usefileViewProvider.getPsi(StdLanguages.XML)
.fileViewProvider.findElementAt(offset,language)
To create a file type that has multiple interspersing trees for different languages, your plugin must contain an extension to the fileType.fileViewProviderFactory
extension point available in the IntelliJ Platform core.
This extension point is declared using the FileTypeExtensionPoint bean class.
To access this extension point, create a Java class that implements the FileViewProviderFactory interface, and in this class, override the createFileViewProvider
method.
To declare the extension to the fileType.fileViewProviderFactory
extension point, to the <extensions>
section of the plugin.xml file, add the following syntax:
<extensions>
<fileType.fileViewProviderFactory filetype="%file_type%" implementationClass="%class_name%" />
</extensions>
Where %file_type%
refers to the type of the file being created (for example, “JFS”), and the %class_name%
refers to the name of your Java class that implements the FileViewProviderFactory
interface.
A PSI (Program Structure Interface) file represents a hierarchy of PSI elements (so-called PSI trees). A single PSI file may include several PSI trees in a particular programming language. A PSI element, in its turn, can have child PSI elements.
PSI elements and operations on the level of individual PSI elements are used to explore the internal structure of source code as it is interpreted by the IntelliJ Platform. For example, you can use PSI elements to perform code analysis, such as code inspections or intention actions.
The PsiElement class is the common base class for PSI elements.
e.getData(LangDataKeys.PSI_ELEMENT)
. Note: if an editor is currently open and the element under caret is a reference, this will return the result of resolving the reference. This may or may not be what you need.PsiFile.findElementAt()
. Note: this returns the lowest level element at the specified offset, which is normally a lexer token. Most likely you should use PsiTreeUtil.getParentOfType()
to find the element you really need.PsiRecursiveElementWalkingVisitor
.PsiReference.resolve()
See PSI Cook Book
This topic considers the concept of projects based on IntelliJ Platform and related subjects, such as modules, facets,libraries, SDK. The project structure and Java classes you can use to manage projects and modules have been considered.
This section briefly discusses the IDEA project structure, project components and related terms. For more information about projects and their components, refer to Project, Module, Library, Facet in the IntelliJ IDEA Web Help.
In the IntelliJ Platform, a project encapsulates all your source code, libraries, and build instructions into a single organizational unit. Everything you do using the IntelliJ Platform SDK is done within the context of a project. A project defines collections referred to as modules and libraries. Depending on the logical and functional requirements to the project, you can create a single-module or a multi-module project.
A module is a discrete unit of functionality that can be run, tested, and debugged independently. Modules includes such things as source code, build scripts, unit tests, deployment descriptors, etc. In the project, each module can use a specific SDK or inherit SDK defined on the project level (see the SDK section later in this document). A module can depend on other modules of the project.
A library is an archive of compiled code (such as JAR files) that your modules depend on. The IntelliJ Platform supports three types of libraries:
.iml
file..ipr
file or in .idea/libraries
.applicationLibraries.xml
file into the~/.IntelliJIdea/config/options
directory. Global libraries are similar to project libraries, but are visible for the different projects.For more information about libraries, refer to Library.
Every project uses a Software Development Kit (SDK). For Java projects, SDK is referred to as JDK (Java Development Kit).
The SDK determines which API library is used to build the project. If your project is multi-module, the project SDK by default is common for all modules within the project.
Optionally, you can configure individual SDK for each module.
For more information about SDKs, see Configuring Global, Project and Module SDKs in the IntelliJ IDEA Web Help.
A facet represents certain configuration, specific for a particular framework/technology, associated with a module. A module can have multiple facets. E.g. Spring specific configuration is stored in a Spring facet.
For more information about facets see Facet and Facet Dependencies in the IntelliJ IDEA Web Help.
From the plugin developer’s point of view, a project can be thought of as follows:
A project consists of one or several modules. Each module includes the plugin source code and so called order entries that refer to SDK and libraries the module uses. By default, all modules uses the project SDK. In addition, amodule can optionally have a set of facets.
This document explains how you can explore and change the structure of projects using API.
This section explains how to complete some common tasks related to management of projects. The Java classes and interfaces that you can use to explore and change the project contents are discussed.
The IntelliJ Platform stores the project configuration data in XML files. The list of those files depends on the pluginproject format.
For file-based format projects, the information core to the project itself (e.g. location of the component modules, compiler settings, etc.) is stored in the %project_name%.ipr
file.
The information about modules the project includes is stored in %module_name%.iml
files. Module files are created for each module.
For directory-based format projects, the project and workspace settings are stored in a number of XML files under the%project_home_directory%/.idea
directory. Each XML file is responsible for its own set of settings and can be recognized by its name: projectCodeStyle.xml
, encodings.xml
, vcs.xml
etc.
As for the file-based format projects, .iml
files describe modules.
To work with projects and project files, you can use the following classes and interfaces:
Project
interface.ProjectRootManager
abstract class.ProjectManager
abstract class.ProjectFileIndex
interface.Note that you don’t need to access project files directly to load or save settings. See Persisting State of Components for more information.
Note that hereafter, the project
variable is of the Project
type. For example, for the opened project, you can get it from an action: Project project = e.getProject();
Use the ProjectRootManager.getContentSourceRoots()
method. To clarify this, consider the following code snippet:
String projectName = project.getName();
StringBuilder sourceRootsList = new StringBuilder();
VirtualFile[] vFiles = ProjectRootManager.getInstance(project).getContentSourceRoots();
for (VirtualFile file : vFiles) {
sourceRootsList.append(file.getUrl()).append("\n");
}
Messages.showInfoMessage("Source roots for the " + projectName + " plugin:\n" + sourceRootsList, "Project Properties");
The IntelliJ Platform provides the ProjectFileIndex
interface you can use to verify whether a file or directory is related to the specified IDEA project. This section explains how you can use this interface.
Use the ProjectRootManager.getFileIndex()
method. For example: ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
To determine a module in the project in question to which the specified virtual file belongs, use theProjectFileIndex.getModuleForFile(virtualFile)
method:
Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(virtualFile);
Note that this method returns null
if the file does not belong to any module.
You can also use the ProjectFileIndex.getContentRootForFile
method to get the module content root to which the specified file or directory belongs:
VirtualFile moduleContentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(virtualFileorDirectory);
Use the ProjectFileIndex.getSourceRootForFile
method. For example:
VirtualFile moduleSourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(virtualFileorDirectory);
Note that this method returns null
if the file or directory does not belong to any source root of modules in the project.
The ProjectFileIndex
interface implements a number of methods you can use to check whether the specified file belongs to the project library classes or library sources.
You can use the following methods:
ProjectFileIndex.isLibraryClassFile(virtualFile)
: Returns true
if the specified virtualFile
is a compiled class file.ProjectFileIndex.isInLibraryClasses(virtualFileorDirectory)
: Returns true
if the specifiedvirtualFileorDirectory
belongs to library classes.ProjectFileIndex.isInLibrarySource(virtualFileorDirectory)
: Returns true
if the specifiedvirtualFileorDirectory
belongs to library sources.Sdk projectSDK = ProjectRootManager.getInstance(project).getProjectSdk();
String projectSDKName = ProjectRootManager.getInstance(project).getProjectSdkName();
ProjectRootManager.getInstance(project).setProjectSdk(Sdk jdk);
ProjectRootManager.getInstance(project).setProjectSdkName(String name);
Note that by default, the project modules use the project SDK. Optionally, you can configure individual SDK for each module.
The IntelliJ Platform provides a number of Java classes and interfaces you can use to work with modules:
ModuleManager
abstract class.Module
interface.ModuleRootManager
abstract class.ModuleRootModel
interface.ModuleUtil
class.ModifiableModuleModel
interface.ModifiableRootModel
interface.This section discusses how to complete some common tasks related to management of modules.
Use the ModuleManager.getModules()
method.
Order entries include SDK, libraries and other modules the module uses. With the IntelliJ IDEA UI, you can view order entries for a module on the Dependencies tab of the Project Structure dialog box.
To explore the module dependencies, use the OrderEnumerator class.
The following code snippet illustrates how you can get classpath (classes root of all dependencies) for a module:
VirtualFile[] roots = ModuleRootManager.getInstance(module).orderEntries().classes().getRoots();
Use the ModuleRootManager.getSdk()
method. This method returns a value of the Sdk type.
The following code snippet illustrates how you can get detailed information on SDK the specified module uses:
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
Sdk SDK = moduleRootManager.getSdk();
String jdkInfo = "Module: " + module.getName() + " SDK: " + SDK.getName() + " SDK version: "
+ SDK.getVersionString() + " SDK home directory: " + SDK.getHomePath();
Use the ModuleRootManager.getDependencies()
method to get an array of the Module
type values or theModuleRootManager.getDependencyModuleNames()
to get an array of module names. To clarify, consider the following code snippet:
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
Module[] dependentModules = moduleRootManager.getDependencies();
String[] dependentModulesNames = moduleRootManager.getDependencyModuleNames();
Use the ModuleManager.getModuleDependentModules(module)
method.
Note that you can also check whether a module (module1) depends on another specified module (module2) using theModuleManager.isModuleDependent
method in the following way:
boolean isDependent = ModuleManager.getInstance(project).isModuleDependent(module1,module2);
To get the project module to which the specified file belongs, use the ModuleUtil.findModuleForFile()
static method.
To clarify, consider the following code snippet:
java String pathToFile = "C:\\users\\firstName.LastName\\plugins\\myPlugin\src\MyAction.java"; VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(pathToFile); Module module = ModuleUtil.findModuleForFile(virtualFile,myProject); String moduleName = module == null ? "Module not found" : module.getName();
To get the project module to which the specified PSI element belongs, use theModuleUtil.findModuleForPsiElement(psiElement)
method.
To get the list of libraries, use OrderEnumerator.forEachLibrary
method. To clarify this, consider the following code snippet that illustrates how to output the list of libraries for the specified module:
final List<String> libraryNames = new ArrayList<String>();
ModuleRootManager.getInstance(module).orderEntries().forEachLibrary(new Processor<Library>() {
@Override
public boolean process(Library library) {
libraryNames.add(library.getName());
return true;
}
});
Messages.showInfoMessage(StringUtil.join(libraryNames, "\n"), "Libraries in Module");
This sample code outputs a list of libraries for the module
module.
The Library
class provides the getUrls
method you can use to get a list of source roots and classes the library includes. To clarify, consider the following code snippet:
StringBuilder roots = new StringBuilder("The " + lib.getName() + " library includes:\n");
roots.append("Sources:\n");
for (String each : lib.getUrls(OrderRootType.SOURCES)) {
roots.append(each).append("\n");
}
roots.append"Classes:\n");
for (String each : lib.getUrls(OrderRootType.CLASSES)) {
strRoots.append(each).append("\n");
}
Messages.showInfoMessage(roots.toString(), "Library Info");
In this sample code, lib
is of the Library type.
Use the FacetManager and Facet classes.
This document describes main classes to work with run configurations and common use case.
The starting point for implementing any run configuration type is the ConfigurationType
interface. The list of available configuration types is shown when a user opens the ‘Edit run configurations’ dialog and executes ‘Add’ action:
Every type there is represented as an instance of ConfigurationType
and registered like below:
<configurationType implementation="org.jetbrains.plugins.gradle.service.execution.GradleExternalTaskConfigurationType" />
The easiest way to implement this interface is to use the ConfigurationTypeBase
base class. In order to use it, you need to inherit from it and to provide the configuration type parameters (ID, name, description and icon) as constructor parameters. In addition to that, you need to call the addFactory()
method to add a configuration factory.
All run configurations are created by the ConfigurationFactory
registered for a particular ConfigurationType
. It’s possible that one ConfigurationType
has more than one ConfigurationFactory
:
The key API of ConfigurationFactory
, and the only method that you’re required to implement, is thecreateTemplateConfiguration
method. This method is called once per project to create the template run configuration.
All real run configurations (loaded from the workspace or created by the user) are called by cloning the template through the createConfiguration
method.
You can customize additional aspects of your configuration factory by overriding the getIcon
, getAddIcon
, getName
and the default settings methods. These additional overrides are optional.
The run configuration itself is represented by the RunConfiguration
interface. A ‘run configuration’ here is some named profile which can be executed, e.g. application started via main()
class, test, remote debug to particular machine/port etc.
Here is an example of a Java run configurations defined for a particular project:
When implementing a run configuration, you may want to use one of the common base classes:
RunConfigurationBase
is a general-purpose superclass that contains the most basic implementation of a run configuration.LocatableConfigurationBase
is a common base class that should be used for configurations that can be created from context by a RunConfigurationProducer
. It supports automatically generating a name for a configuration from its settings and keeping track of whether the name was changed by the user.ModuleBasedConfiguration
is a base class for a configuration that is associated with a specific module (for example, Java run configurations use the selected module to determine the run classpath).That common run configuration settings might be modified via:
RunConfiguration
-specific UI. That is handled by SettingsEditor
:
getComponent()
method is called by the IDE and shows run configuration specific UI.resetFrom()
is called to discard all non-confirmed user changes made via that UI.applyTo()
is called to confirm the changes, i.e. copy current UI state into the target settings object.That run configuration settings are persistent, i.e. they are stored at file system and loaded back on the IDE startup. That is performed via writeExternal()
and readExternal()
methods of RunConfiguration
class correspondingly.
The actual configurations stored by the IntelliJ Platform are represented by instances of theRunnerAndConfigurationSettings
class, which combines a run configuration with runner-specific settings, as well as keeping track of certain run configuration flags such as “temporary” or “singleton”.
Dealing with instances of this class becomes necessary when you need to create run configurations from code. This is accomplished with the following two steps:
RunManager.createConfiguration()
creates an instance of RunnerAndConfigurationSettings
.RunManager.addConfiguration()
makes it persistent by adding it to either the list of shared configurations stored in a project, or to the list of local configurations stored in the workspace file.Most run configurations contain references to classes, files or directories in their settings, and these settings usually need to be updated when the corresponding element is renamed or moved.
In order to support that, your run configuration needs to implement the RefactoringListenerProvider
interface.
In your implementation of getRefactoringElementListener()
, you need to check whether the element being refactored is the one that your run configuration refers to, and if it is, you return a RefactoringElementListener
that updates your configuration according to the new name and location of the element.
Many plugins support automatic creation of run configurations from context, so that the user can click, for example, on an application or test class and automatically run it using the correct run configuration type. In order to support that, you need to provide an implementation of the RunConfigurationProducer
interface and to register it as<runConfigurationProducer>
in your plugin.xml
. (Note that this API has been redesigned in IntelliJ IDEA 13; the oldRuntimeConfigurationProducer
is a much more confusing version of the same API).
The two main methods that you need to implement are:
setupConfigurationFromContext
receives a blank configuration of your type and a ConfigurationContext
containing information about a source code location (accessible by calling getLocation()
or getPsiLocation()
). Your implementation needs to check whether the location is applicable for your configuration type (for example, if it’s in a file of the language you’re supporting). If not, you need to return false, and if it is, you need to put the correct context-specific settings into the run configuration and return true.isConfigurationFromContext
checks if the specified configuration of your type was created from the specified context. Implementing this method allows you to reuse an existing run configuration which is applicable to the current context instead of creating a new one and possibly ignoring the customisations the user has performed in the existing one.Note that, in order to support automatic naming of configurations created from context, your configuration should useLocatableConfigurationBase
as the base class.
The standard execution of a run action goes through the following steps:
ExecutionEnvironment
object is created. This object aggregates all the settings required to execute the process, as well as the selected ProgramRunner
.ProgramRunner.execute()
is called, receiving the executor and the execution environment.Implementations of ProgramRunner.execute()
go through the following steps to execute the process:
RunProfile.getState()
method is called to create a RunProfileState
object, describing a process about to be started. At this stage, the command line parameters, environment variables and other information required to start the process is initialized.RunProfileState.execute()
is called. It starts the process, attaches a ProcessHandler
to its input and output streams, creates a console to display the process output, and returns an ExecutionResult
object aggregating the console and the process handler.RunContentBuilder
object is created and invoked to display the execution console in a tab of the Run or Debug toolwindow.The Executor
interface describes a specific way of executing any possible run configuration.
The three default executors provided by the IntelliJ Platform by default are Run, Debug and Run with Coverage. Each executor gets its own toolbar button, which starts the selected run configuration using this executor, and its own context menu item for starting a configuration using this executor.
As a plugin developer, you normally don’t need to implement the Executor
interface. However, it can be useful, for example, if you’re implementing a profiler integration and want to provide the possibility to execute any configuration with profiling.
The RunProfileState
interface comes up in every run configuration implementation as the return valueRunProfile.getState()
. It describes a process which is ready to be started and holds the information like the command line, current working directory, and environment variables for the process to be started. (The existence ofRunProfileState
as a separate step in the execution flow allows run configuration extensions and other components to patch the configuration and to modify the parameters before it gets executed.)
The standard base class used as implementation of RunProfileState
is CommandLineState
. It contains the logic for putting together a running process and a console into an ExecutionResult
, but doesn’t know anything how the process is actually started. For starting the process, it’s best to use the GeneralCommandLine
class, which takes care of setting up the command line parameters and executing the process.
Alternatively, if the process you need to run is a JVM-based one, you can use the JavaCommandLineState
base class. It knows about the command line parameters of the JVM and can take care of details like calculating the classpath for the JVM.
To monitor the execution of a process and capture its output, the OSProcessHandler
class is normally used. Once you’ve created an instance of OSProcessHandler
from either a command line or a Process object, you need to call thestartNotify()
method to start capturing its output. You may also want to attach a ProcessTerminatedListener
to theOSProcessHandler
, so that the exit status of the process will be displayed in the console.
If you’re using CommandLineState
, a console view will be automatically created and attached to the output of the process. Alternatively, you can arrange this yourself:
TextConsoleBuilderFactory.createBuilder(project).getConsole()
creates a ConsoleView
instanceConsoleView.attachToProcess()
attaches it to the output of a process.If the process you’re running uses ANSI escape codes to color its output, the ColoredProcessHandler
class will parse it and display the colors in the IntelliJ console.
Console filters allow you to convert certain strings found in the process output to clickable hyperlinks. To attach a filter to the console, use CommandLineState.addConsoleFilters()
or, if you’re creating a console manually,TextConsoleBuilder.addFilter()
.
Two common filter implementations you may want to reuse are RegexpFilter
and UrlFilter
.
If you have an existing run configuration that you need to execute, the easiest way to do so is to useProgramRunnerUtil.executeConfiguration()
. The method takes a Project
, a RunnerAndConfigurationSettings
, as well as an Executor
. To get the RunnerAndConfigurationSettings
for an existing configuration, you can use, for example,RunManager.getConfigurationSettings(ConfigurationType)
. As the last parameter, you normally pass eitherDefaultRunExecutor.getRunExecutorInstance()
or DefaultDebugExecutor.getDebugExecutorInstance()
.
标签:fse sample arraylist elements compile gradle delete htm seq
原文地址:http://www.cnblogs.com/liqiking/p/6810444.html