module util::IDEServices
Usage
import util::IDEServices;
Dependencies
extend analysis::diff::edits::TextEdits;
import analysis::diff::edits::ExecuteTextEdits;
extend Content;
extend Message;
function browse
Open a browser for a given location.
void browse(loc uri, str title = "<uri>", ViewColumn viewColumn = normalViewColumn(1))
Starts an interactive browser for a given URI, typically in a tab embedded in the IDE. However, this depends on the current IDE context. Some editors do not support this feature. A browser window for the OS default browser will be started instead.
function edit
Open an editor for file at a given location.
void edit(loc uri, ViewColumn viewColumn = activeViewColumn())
Based on the current IDE context an editor will be "opened". This means for most IDEs that the language services associated with the file extension will be activated. However, this depends entirely on the IDE and the currently registered languages.
function applyDocumentsEdits
Let the IDE apply a list of document edits.
void applyDocumentsEdits(list[FileSystemChange] edits)
Asks the IDE to apply document edits as defined in the standard library module analysis::diff::edits::TextEdits, according to the semantics defined in analysis::diff::edits::ExecuteTextEdits. However, the IDE can take care of these changes in order to provide important UI experience features such as "preview" and "undo".
Typically a call to this IDE service method is included in the implementation of refactoring and quick-fix features of the language service protocol.
function applyFileSystemEdits
void applyFileSystemEdits(list[FileSystemChange] edits)
function showInteractiveContent
Asks the IDE to show a "browser window" with the given interactive Content.
void showInteractiveContent(Content content, str title=content.title, ViewColumn viewColumn=content.viewColumn)
Just like Browse, with the important distinction that this starts both a web client and a web server.
Benefits
- quickly spin-up and manage interactive visuals without worrying about garbage collection and memory leaks, or port numbers
- shows visuals inside the current IDE. Combines very well with Edit to show visuals side-by-side with code.
Pitfalls
- the web servers will remain active until 30 minutes after
the last interaction. After that a
404(not found) http error will be produced and Show Interactive Content has to be called again to re-activate the visual.
function showMessage
void showMessage(Message message)
function logMessage
void logMessage(Message message)
function registerDiagnostics
void registerDiagnostics(list[Message] messages)
function unregisterDiagnostics
void unregisterDiagnostics(list[loc] resources)
data Message
Fixes are an extension to error messages that allow for interactive code fixes in the IDE.
data Message (list[CodeAction] fixes = [])
This definition adds lists of Code Actions as optional fields to any message. In collaboration with a language server, these messages then lead to interactive quick fixes in IDEs.
data CodeAction
Code actions bundle synchronous text edits and command execution with a title for the menu option.
data CodeAction (list[FileSystemChange] edits = [], Command command = noop(), str title = command.title)
= action()
;
For any action instance, the IDE will:
- show a menu option with the given title.
- if the title is selected, then the (optional) edits will be executed first
- and then the (optional) command is executed via the
executionservice of the language service protocol.
data Command
Commands are an open data-type for describing interactive functions that may be attached to CodeActions.
data Command (str title="")
= noop()
;
Commands are simply immutable constructors with parameters. To use a command you can attach it to a Message via a Code Action, and then have it executed by the respective language server.
function testCodeAction
Utility function for testing code actions.
value testCodeAction(CodeAction action, value (Command _) evaluator = value (noop()) { return true; })
actionis the action to executeevaluatoris used to evaluate action.command if it is present.- the return value is the return value of the evaluated command, or
trueif no command is present.
Benefits
- test code actions outside of the IDE context, for example while running unit tests.
- this function is synchronous and blocks until the IO is finished. After running it you can test for changed file contents without waiting, in most cases (see pitfalls).
Pitfalls
- Code Actions may use the other features of IDEServices, and thus start editors or browsers as side-effects.
- Code Actions code actions with FileSystemChanges will write to disk and change the original files.
- Commands can only be executed by a parametrized command `evaluator``; if you do not provide it then this test function will throw Call Failed exceptions for every unsupported (Command.
- (Commands can start asynchronous effects by calling non-blocking functions that schedule other effects. An example is the starting and running of web Content via Show Interactive Content. Testing properties of the rendered content will require the use of asynchronous testing frameworks, like Selenium.
- Never call Test Code Action to execute actions in an interactive context. That must be done by the IDE client to synchronize the contents of editors and parse trees, etc. This function is only for unit testing code actions.