use of org.rstudio.studio.client.workbench.views.source.editors.text.ace.Position in project rstudio by rstudio.
the class LintManager method showLint.
private void showLint(LintContext context, JsArray<LintItem> lint) {
if (docDisplay_.isPopupVisible() || !docDisplay_.isFocused())
return;
// hasn't moved.
if (context.excludeCurrentStatement && docDisplay_.getCursorPosition().isEqualTo(context.cursorPosition)) {
Position pos = context.cursorPosition;
JsArray<LintItem> filteredLint = JsArray.createArray().cast();
for (int i = 0; i < lint.length(); i++) if (!lint.get(i).asRange().contains(pos))
filteredLint.push(lint.get(i));
docDisplay_.showLint(filteredLint);
return;
}
docDisplay_.showLint(lint);
return;
}
use of org.rstudio.studio.client.workbench.views.source.editors.text.ace.Position in project rstudio by rstudio.
the class EditingTargetInlineChunkExecution method execute.
public void execute(Range range) {
// synthesize an identifier for this chunk execution
final String chunkId = "i" + StringUtil.makeRandomId(12);
// are, remove it to make way for the new one
for (ChunkInlineOutput output : outputs_.values()) {
if (output.range().isEqualTo(range)) {
if (output.state() == ChunkInlineOutput.State.Finished) {
// remove old, completed output for this input
output.hide();
outputs_.remove(output.chunkId());
} else {
// unintended duplicate.
return;
}
}
}
// create dummy scope for execution
Scope scope = Scope.createRScopeNode(chunkId, range.getStart(), range.getEnd(), Scope.SCOPE_TYPE_CHUNK);
// create popup panel to host output
final ChunkInlineOutput output = new ChunkInlineOutput(chunkId, display_.createAnchoredSelection(range.getStart(), range.getEnd()));
// auto dismiss the panel when the cursor leaves the inline chunk
final Mutable<HandlerRegistration> cursorHandler = new Mutable<HandlerRegistration>();
cursorHandler.set(display_.addCursorChangedHandler(new CursorChangedHandler() {
@Override
public void onCursorChanged(CursorChangedEvent event) {
Position position = event.getPosition();
if (!output.range().contains(position)) {
output.hide();
}
}
}));
// when the popup is dismissed, clean up local state
output.addCloseHandler(new CloseHandler<PopupPanel>() {
@Override
public void onClose(CloseEvent<PopupPanel> event) {
outputs_.remove(chunkId);
cursorHandler.get().removeHandler();
}
});
// render offscreen until complete
output.setPopupPosition(-100000, -100000);
output.show();
outputs_.put(chunkId, output);
SendToChunkConsoleEvent event = new SendToChunkConsoleEvent(docId_, scope, range, NotebookQueueUnit.EXEC_SCOPE_INLINE);
events_.fireEvent(event);
}
use of org.rstudio.studio.client.workbench.views.source.editors.text.ace.Position in project rstudio by rstudio.
the class TextEditingTarget method onUnfold.
@Handler
void onUnfold() {
if (useScopeTreeFolding()) {
Range range = Range.fromPoints(docDisplay_.getSelectionStart(), docDisplay_.getSelectionEnd());
if (range.isEmpty()) {
// If no selection, either:
//
// 1) Unfold a fold containing the cursor, or
// 2) Unfold the closest fold on the current row.
Position pos = docDisplay_.getCursorPosition();
AceFold containingCandidate = null;
AceFold startCandidate = null;
AceFold endCandidate = null;
for (AceFold f : JsUtil.asIterable(docDisplay_.getFolds())) {
// Check to see whether this fold contains the cursor position.
if (f.getRange().contains(pos)) {
if (containingCandidate == null || containingCandidate.getRange().contains(f.getRange())) {
containingCandidate = f;
}
}
if (startCandidate == null && f.getStart().getRow() == pos.getRow() && f.getStart().getColumn() >= pos.getColumn()) {
startCandidate = f;
}
if (startCandidate == null && f.getEnd().getRow() == pos.getRow() && f.getEnd().getColumn() <= pos.getColumn()) {
endCandidate = f;
}
}
if (containingCandidate != null) {
docDisplay_.unfold(containingCandidate);
} else if (startCandidate == null ^ endCandidate == null) {
docDisplay_.unfold(startCandidate != null ? startCandidate : endCandidate);
} else if (startCandidate != null && endCandidate != null) {
// Both are candidates; see which is closer
int startDelta = startCandidate.getStart().getColumn() - pos.getColumn();
int endDelta = pos.getColumn() - endCandidate.getEnd().getColumn();
docDisplay_.unfold(startDelta <= endDelta ? startCandidate : endCandidate);
}
} else {
// If selection, unfold the selection
docDisplay_.unfold(range);
}
} else {
int row = docDisplay_.getSelectionStart().getRow();
docDisplay_.unfold(row);
}
}
use of org.rstudio.studio.client.workbench.views.source.editors.text.ace.Position in project rstudio by rstudio.
the class AceEditorWidget method updateAnnotations.
private void updateAnnotations(AceDocumentChangeEventNative event) {
Range range = event.getRange();
ArrayList<AnchoredAceAnnotation> annotations = new ArrayList<AnchoredAceAnnotation>();
for (int i = 0; i < annotations_.size(); i++) {
AnchoredAceAnnotation annotation = annotations_.get(i);
Position pos = annotation.anchor_.getPosition();
if (!range.contains(pos))
annotations.add(annotation);
else
annotation.detach();
}
annotations_ = annotations;
}
use of org.rstudio.studio.client.workbench.views.source.editors.text.ace.Position in project rstudio by rstudio.
the class TextEditingTarget method initialize.
public void initialize(final SourceDocument document, FileSystemContext fileContext, FileType type, Provider<String> defaultNameProvider) {
id_ = document.getId();
fileContext_ = fileContext;
fileType_ = (TextFileType) type;
codeExecution_ = new EditingTargetCodeExecution(this, docDisplay_, getId(), this);
extendedType_ = document.getExtendedType();
extendedType_ = rmarkdownHelper_.detectExtendedType(document.getContents(), extendedType_, fileType_);
themeHelper_ = new TextEditingTargetThemeHelper(this, events_);
docUpdateSentinel_ = new DocUpdateSentinel(server_, docDisplay_, document, globalDisplay_.getProgressIndicator("Save File"), dirtyState_, events_);
view_ = new TextEditingTargetWidget(this, docUpdateSentinel_, commands_, prefs_, fileTypeRegistry_, docDisplay_, fileType_, extendedType_, events_, session_);
roxygenHelper_ = new RoxygenHelper(docDisplay_, view_);
// create notebook and forward resize events
chunks_ = new TextEditingTargetChunks(this);
notebook_ = new TextEditingTargetNotebook(this, chunks_, view_, docDisplay_, dirtyState_, docUpdateSentinel_, document, releaseOnDismiss_, dependencyManager_);
view_.addResizeHandler(notebook_);
// ensure that Makefile and Makevars always use tabs
name_.addValueChangeHandler(new ValueChangeHandler<String>() {
@Override
public void onValueChange(ValueChangeEvent<String> event) {
if ("Makefile".equals(event.getValue()) || "Makefile.in".equals(event.getValue()) || "Makefile.win".equals(event.getValue()) || "Makevars".equals(event.getValue()) || "Makevars.in".equals(event.getValue()) || "Makevars.win".equals(event.getValue())) {
docDisplay_.setUseSoftTabs(false);
}
}
});
name_.setValue(getNameFromDocument(document, defaultNameProvider), true);
String contents = document.getContents();
docDisplay_.setCode(contents, false);
// Load and apply folds.
final ArrayList<Fold> folds = Fold.decode(document.getFoldSpec());
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
for (Fold fold : folds) docDisplay_.addFold(fold.getRange());
}
});
// Load and apply Vim marks (if they exist).
if (document.getProperties().hasKey("marks")) {
final String marksSpec = document.getProperties().getString("marks");
final JsMap<Position> marks = VimMarks.decode(marksSpec);
// Time out the marks setting just to avoid conflict with other
// mutations of the editor.
new Timer() {
@Override
public void run() {
docDisplay_.setMarks(marks);
}
}.schedule(100);
}
registerPrefs(releaseOnDismiss_, prefs_, docDisplay_, document);
// Initialize sourceOnSave, and keep it in sync
view_.getSourceOnSave().setValue(document.sourceOnSave(), false);
view_.getSourceOnSave().addValueChangeHandler(new ValueChangeHandler<Boolean>() {
public void onValueChange(ValueChangeEvent<Boolean> event) {
docUpdateSentinel_.setSourceOnSave(event.getValue(), globalDisplay_.getProgressIndicator("Error Saving Setting"));
}
});
if (document.isDirty())
dirtyState_.markDirty(false);
else
dirtyState_.markClean();
docDisplay_.addValueChangeHandler(new ValueChangeHandler<Void>() {
public void onValueChange(ValueChangeEvent<Void> event) {
dirtyState_.markDirty(true);
docDisplay_.clearSelectionHistory();
}
});
docDisplay_.addFocusHandler(new FocusHandler() {
public void onFocus(FocusEvent event) {
// let anyone listening know this doc just got focus
events_.fireEvent(new DocFocusedEvent(getPath(), getId()));
if (queuedCollabParams_ != null) {
// of one
if (docDisplay_ != null && !docDisplay_.hasActiveCollabSession()) {
beginQueuedCollabSession();
}
}
// check to see if the file's been saved externally--we do this even
// in a collaborative editing session so we can get delete
// notifications
Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
public boolean execute() {
if (view_.isAttached())
checkForExternalEdit();
return false;
}
}, 500);
}
});
if (fileType_.isR()) {
docDisplay_.addBreakpointSetHandler(new BreakpointSetEvent.Handler() {
@Override
public void onBreakpointSet(BreakpointSetEvent event) {
if (event.isSet()) {
Breakpoint breakpoint = null;
// don't try to set breakpoints in unsaved code
if (isNewDoc()) {
view_.showWarningBar("Breakpoints cannot be set until " + "the file is saved.");
return;
}
// don't try to set breakpoints if the R version is too old
if (!session_.getSessionInfo().getHaveSrcrefAttribute()) {
view_.showWarningBar("Editor breakpoints require R 2.14 " + "or newer.");
return;
}
Position breakpointPosition = Position.create(event.getLineNumber() - 1, 1);
// if we're not in function scope, or this is a Shiny file,
// set a top-level (aka. Shiny-deferred) breakpoint
ScopeFunction innerFunction = null;
if (extendedType_ == null || !extendedType_.startsWith(SourceDocument.XT_SHINY_PREFIX))
innerFunction = docDisplay_.getFunctionAtPosition(breakpointPosition, false);
if (innerFunction == null || !innerFunction.isFunction() || StringUtil.isNullOrEmpty(innerFunction.getFunctionName())) {
breakpoint = breakpointManager_.setTopLevelBreakpoint(getPath(), event.getLineNumber());
} else // the scope tree will find nested functions, but in R these
// are addressable only as substeps of the parent function.
// keep walking up the scope tree until we've reached the top
// level function.
{
while (innerFunction.getParentScope() != null && innerFunction.getParentScope().isFunction()) {
innerFunction = (ScopeFunction) innerFunction.getParentScope();
}
String functionName = innerFunction.getFunctionName();
breakpoint = breakpointManager_.setBreakpoint(getPath(), functionName, event.getLineNumber(), dirtyState().getValue() == false);
}
docDisplay_.addOrUpdateBreakpoint(breakpoint);
} else {
breakpointManager_.removeBreakpoint(event.getBreakpointId());
}
updateBreakpointWarningBar();
}
});
docDisplay_.addBreakpointMoveHandler(new BreakpointMoveEvent.Handler() {
@Override
public void onBreakpointMove(BreakpointMoveEvent event) {
breakpointManager_.moveBreakpoint(event.getBreakpointId());
}
});
}
// validate required components (e.g. Tex, knitr, C++ etc.)
checkCompilePdfDependencies();
rmarkdownHelper_.verifyPrerequisites(view_, fileType_);
syncFontSize(releaseOnDismiss_, events_, view_, fontSizeManager_);
final String rTypeId = FileTypeRegistry.R.getTypeId();
releaseOnDismiss_.add(prefs_.softWrapRFiles().addValueChangeHandler(new ValueChangeHandler<Boolean>() {
public void onValueChange(ValueChangeEvent<Boolean> evt) {
if (fileType_.getTypeId().equals(rTypeId))
view_.adaptToFileType(fileType_);
}
}));
releaseOnDismiss_.add(events_.addHandler(FileChangeEvent.TYPE, new FileChangeHandler() {
@Override
public void onFileChange(FileChangeEvent event) {
// screen out adds and events that aren't for our path
FileChange fileChange = event.getFileChange();
if (fileChange.getType() == FileChange.ADD)
return;
else if (!fileChange.getFile().getPath().equals(getPath()))
return;
// always check for changes if this is the active editor
if (commandHandlerReg_ != null) {
checkForExternalEdit();
} else // this will show a confirmation dialog
if (event.getFileChange().getType() == FileChange.MODIFIED && dirtyState().getValue() == false) {
checkForExternalEdit();
}
}
}));
spelling_ = new TextEditingTargetSpelling(docDisplay_, docUpdateSentinel_);
// show/hide the debug toolbar when the dirty state changes. (note:
// this doesn't yet handle the case where the user saves the document,
// in which case we should still show some sort of warning.)
dirtyState().addValueChangeHandler(new ValueChangeHandler<Boolean>() {
public void onValueChange(ValueChangeEvent<Boolean> evt) {
updateDebugWarningBar();
}
});
// find all of the debug breakpoints set in this document and replay them
// onto the edit surface
ArrayList<Breakpoint> breakpoints = breakpointManager_.getBreakpointsInFile(getPath());
for (Breakpoint breakpoint : breakpoints) {
docDisplay_.addOrUpdateBreakpoint(breakpoint);
}
if (extendedType_.equals(SourceDocument.XT_RMARKDOWN)) {
// populate the popup menu with a list of available formats
updateRmdFormatList();
setRMarkdownBehaviorEnabled(true);
}
view_.addRmdFormatChangedHandler(new RmdOutputFormatChangedEvent.Handler() {
@Override
public void onRmdOutputFormatChanged(RmdOutputFormatChangedEvent event) {
setRmdFormat(event.getFormat());
}
});
syncPublishPath(document.getPath());
initStatusBar();
}
Aggregations