private static void saveIndent(AnswerPlaceholder placeholder, CCState state, boolean visible) { Document document = state.getEditor().getDocument(); int offset = placeholder.getOffset(); int lineNumber = document.getLineNumber(offset); int nonSpaceCharOffset = DocumentUtil.getFirstNonSpaceCharOffset(document, lineNumber); int newOffset = offset; int endOffset = offset + placeholder.getRealLength(); if (!visible && nonSpaceCharOffset == offset) { newOffset = document.getLineStartOffset(lineNumber); } if (visible) { newOffset = DocumentUtil.getFirstNonSpaceCharOffset(document, offset, endOffset); } placeholder.setOffset(newOffset); int delta = offset - newOffset; placeholder.setPossibleAnswer(document.getText(TextRange.create(newOffset, newOffset + delta + placeholder.getRealLength()))); String oldTaskText = placeholder.getTaskText(); if (delta >= 0) { placeholder.setTaskText(StringUtil.repeat(" ", delta) + oldTaskText); } else { String newTaskText = oldTaskText.substring(Math.abs(delta)); placeholder.setTaskText(newTaskText); } }
public void actionPerformed(AnActionEvent e) { Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) { return; } DebuggerManagerEx debugManager = DebuggerManagerEx.getInstanceEx(project); if (debugManager == null) { return; } final BreakpointManager manager = debugManager.getBreakpointManager(); final PlaceInDocument place = getPlace(e); if(place != null && DocumentUtil.isValidOffset(place.getOffset(), place.getDocument())) { Breakpoint breakpoint = manager.findBreakpoint(place.getDocument(), place.getOffset(), MethodBreakpoint.CATEGORY); if(breakpoint == null) { manager.addMethodBreakpoint(place.getDocument(), place.getDocument().getLineNumber(place.getOffset())); } else { manager.removeBreakpoint(breakpoint); } } }
@Nullable public static PsiElement getFirstElementOnTheLine(PsiLambdaExpression lambda, Document document, int line) { ApplicationManager.getApplication().assertReadAccessAllowed(); TextRange lineRange = DocumentUtil.getLineTextRange(document, line); if (!intersects(lineRange, lambda)) return null; PsiElement body = lambda.getBody(); if (body == null || !intersects(lineRange, body)) return null; if (body instanceof PsiCodeBlock) { for (PsiStatement statement : ((PsiCodeBlock)body).getStatements()) { if (intersects(lineRange, statement)) { return statement; } } return null; } return body; }
@NotNull public static List<RangeHighlighter> createLineMarker(@NotNull final Editor editor, int line, @NotNull final SeparatorPlacement placement, @Nullable TextDiffType type, @NotNull LineSeparatorRenderer renderer, boolean applied) { // We won't use addLineHighlighter as it will fail to add marker into empty document. //RangeHighlighter highlighter = editor.getMarkupModel().addLineHighlighter(line, HighlighterLayer.SELECTION - 1, null); int offset = DocumentUtil.getFirstNonSpaceCharOffset(editor.getDocument(), line); RangeHighlighter highlighter = editor.getMarkupModel() .addRangeHighlighter(offset, offset, LINE_MARKER_LAYER, null, HighlighterTargetArea.LINES_IN_RANGE); highlighter.setLineSeparatorPlacement(placement); highlighter.setLineSeparatorRenderer(renderer); if (type == null || applied) return Collections.singletonList(highlighter); TextAttributes stripeAttributes = getStripeTextAttributes(type, editor); RangeHighlighter stripeHighlighter = editor.getMarkupModel() .addRangeHighlighter(offset, offset, STRIPE_LAYER, stripeAttributes, HighlighterTargetArea.LINES_IN_RANGE); return ContainerUtil.list(highlighter, stripeHighlighter); }
/** * Read action will be taken automatically */ public static <RESULT> RESULT visit(@NotNull XSourcePosition position, @NotNull Project project, @NotNull Visitor<RESULT> visitor, RESULT defaultResult) { AccessToken token = ReadAction.start(); try { Document document = FileDocumentManager.getInstance().getDocument(position.getFile()); PsiFile file = document == null || document.getTextLength() == 0 ? null : PsiDocumentManager.getInstance(project).getPsiFile(document); if (file == null) { return defaultResult; } int positionOffset; int column = position instanceof SourceInfo ? Math.max(((SourceInfo)position).getColumn(), 0) : 0; try { positionOffset = column == 0 ? DocumentUtil.getFirstNonSpaceCharOffset(document, position.getLine()) : document.getLineStartOffset(position.getLine()) + column; } catch (IndexOutOfBoundsException ignored) { return defaultResult; } PsiElement element = file.findElementAt(positionOffset); return element == null ? defaultResult : visitor.visit(element, positionOffset, document); } finally { token.finish(); } }
@Override protected void changedUpdateImpl(@NotNull DocumentEvent e) { // todo Denis Zhdanov DocumentEventImpl event = (DocumentEventImpl)e; final boolean shouldTranslateViaDiff = isValid() && PersistentRangeMarkerUtil.shouldTranslateViaDiff(event, this); boolean wasTranslatedViaDiff = shouldTranslateViaDiff; if (shouldTranslateViaDiff) { wasTranslatedViaDiff = translatedViaDiff(e, event); } if (!wasTranslatedViaDiff) { super.changedUpdateImpl(e); if (isValid()) { myLine = getDocument().getLineNumber(getStartOffset()); int endLine = getDocument().getLineNumber(getEndOffset()); if (endLine != myLine) { setIntervalEnd(getDocument().getLineEndOffset(myLine)); } } } if (isValid() && getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE) { setIntervalStart(DocumentUtil.getFirstNonSpaceCharOffset(getDocument(), myLine)); setIntervalEnd(getDocument().getLineEndOffset(myLine)); } }
@Override public void executeWriteAction(Editor editor, Caret caret, DataContext dataContext) { if (editor.getSelectionModel().hasSelection()) { int selStart = editor.getSelectionModel().getSelectionStart(); int selEnd = editor.getSelectionModel().getSelectionEnd(); if (selEnd > selStart && DocumentUtil.isAtLineStart(selEnd, editor.getDocument())) { selEnd--; } VisualPosition rangeStart = editor.offsetToVisualPosition(Math.min(selStart, selEnd)); VisualPosition rangeEnd = editor.offsetToVisualPosition(Math.max(selStart, selEnd)); final Couple<Integer> copiedRange = DuplicateAction.duplicateLinesRange(editor, editor.getDocument(), rangeStart, rangeEnd); if (copiedRange != null) { editor.getSelectionModel().setSelection(copiedRange.first, copiedRange.second); } } else { VisualPosition caretPos = editor.getCaretModel().getVisualPosition(); DuplicateAction.duplicateLinesRange(editor, editor.getDocument(), caretPos, caretPos); } }
private void updateTextElement(final PsiElement elt) { final String newText = getNewText(elt); if (newText == null || Comparing.strEqual(newText, myEditor.getDocument().getText())) return; DocumentUtil.writeInRunUndoTransparentAction(new Runnable() { @Override public void run() { Document fragmentDoc = myEditor.getDocument(); fragmentDoc.setReadOnly(false); fragmentDoc.replaceString(0, fragmentDoc.getTextLength(), newText); fragmentDoc.setReadOnly(true); myEditor.getCaretModel().moveToOffset(0); myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); } }); }
private static void reformatBlock(final Project project, final Editor editor, final int startOffset, final int endOffset) { PsiDocumentManager.getInstance(project).commitAllDocuments(); Runnable task = new Runnable() { @Override public void run() { PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); try { CodeStyleManager.getInstance(project).reformatRange(file, startOffset, endOffset, true); } catch (IncorrectOperationException e) { LOG.error(e); } } }; if (endOffset - startOffset > 1000) { DocumentUtil.executeInBulk(editor.getDocument(), true, task); } else { task.run(); } }
@NotNull protected String addToHistoryInner(@NotNull final TextRange textRange, @NotNull final EditorEx editor, boolean erase, final boolean preserveMarkup) { ApplicationManager.getApplication().assertIsDispatchThread(); String result = addTextRangeToHistory(textRange, editor, preserveMarkup); if (erase) { DocumentUtil.writeInRunUndoTransparentAction(new Runnable() { @Override public void run() { editor.getDocument().deleteString(textRange.getStartOffset(), textRange.getEndOffset()); } }); } // always scroll to end on user input scrollToEnd(); return result; }
public void updateText(@NotNull final Producer<String> contentProducer) { myAlarm.cancelAllRequests(); myAlarm.addRequest(new Runnable() { @Override public void run() { if (!isDisposed) { final String newText = contentProducer.produce(); if (StringUtil.isEmpty(newText)) { hide(); } else if (!myEditor.getDocument().getText().equals(newText)) { DocumentUtil.writeInRunUndoTransparentAction(new Runnable() { @Override public void run() { myEditor.getDocument().setText(newText); } }); } } } }, 100); }
public static void invokeOnTheFlyImportOptimizer(@NotNull final Runnable runnable, @NotNull final PsiFile file, @NotNull final Editor editor) { final long stamp = editor.getDocument().getModificationStamp(); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { if (file.getProject().isDisposed() || editor.isDisposed() || editor.getDocument().getModificationStamp() != stamp) return; //no need to optimize imports on the fly during undo/redo final UndoManager undoManager = UndoManager.getInstance(editor.getProject()); if (undoManager.isUndoInProgress() || undoManager.isRedoInProgress()) return; PsiDocumentManager.getInstance(file.getProject()).commitAllDocuments(); String beforeText = file.getText(); final long oldStamp = editor.getDocument().getModificationStamp(); DocumentUtil.writeInRunUndoTransparentAction(runnable); if (oldStamp != editor.getDocument().getModificationStamp()) { String afterText = file.getText(); if (Comparing.strEqual(beforeText, afterText)) { String path = file.getViewProvider().getVirtualFile().getPath(); LOG.error("Import optimizer hasn't optimized any imports", new Attachment(path, afterText)); } } } }); }
public void reset() { myDisplayName = myCopyrightProfile.getName(); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { DocumentUtil.writeInRunUndoTransparentAction(new Runnable() { @Override public void run() { myEditor.getDocument().setText(EntityUtil.decode(myCopyrightProfile.getNotice())); } }); } }); myKeywordTf.setText(myCopyrightProfile.getKeyword()); myAllowReplaceTextField.setText(myCopyrightProfile.getAllowReplaceKeyword()); }
@Nonnull public List<RangeHighlighter> done() { // We won't use addLineHighlighter as it will fail to add marker into empty document. //RangeHighlighter highlighter = editor.getMarkupModel().addLineHighlighter(line, HighlighterLayer.SELECTION - 1, null); int offset = DocumentUtil.getFirstNonSpaceCharOffset(editor.getDocument(), line); RangeHighlighter highlighter = editor.getMarkupModel() .addRangeHighlighter(offset, offset, LINE_MARKER_LAYER, null, HighlighterTargetArea.LINES_IN_RANGE); highlighter.setLineSeparatorPlacement(placement); highlighter.setLineSeparatorRenderer(renderer); highlighter.setLineMarkerRenderer(gutterRenderer); if (type == null || resolved) return Collections.singletonList(highlighter); TextAttributes stripeAttributes = getStripeTextAttributes(type, editor); RangeHighlighter stripeHighlighter = editor.getMarkupModel() .addRangeHighlighter(offset, offset, STRIPE_LAYER, stripeAttributes, HighlighterTargetArea.LINES_IN_RANGE); return ContainerUtil.list(highlighter, stripeHighlighter); }
@RequiredDispatchThread public static void executeWriteCommand(@javax.annotation.Nullable Project project, @Nonnull Document document, @javax.annotation.Nullable String commandName, @javax.annotation.Nullable String commandGroupId, @Nonnull UndoConfirmationPolicy confirmationPolicy, boolean underBulkUpdate, @Nonnull Runnable task) { if (!makeWritable(project, document)) { VirtualFile file = FileDocumentManager.getInstance().getFile(document); LOG.warn("Document is read-only" + (file != null ? ": " + file.getPresentableName() : "")); return; } ApplicationManager.getApplication().runWriteAction(() -> { CommandProcessor.getInstance().executeCommand(project, () -> { if (underBulkUpdate) { DocumentUtil.executeInBulk(document, true, task); } else { task.run(); } }, commandName, commandGroupId, confirmationPolicy, document); }); }
@Override protected void changedUpdateImpl(@Nonnull DocumentEvent e) { // todo Denis Zhdanov DocumentEventImpl event = (DocumentEventImpl)e; final boolean shouldTranslateViaDiff = isValid() && PersistentRangeMarkerUtil.shouldTranslateViaDiff(event, getStartOffset(), getEndOffset()); boolean wasTranslatedViaDiff = shouldTranslateViaDiff; if (shouldTranslateViaDiff) { wasTranslatedViaDiff = translatedViaDiff(e, event); } if (!wasTranslatedViaDiff) { super.changedUpdateImpl(e); if (isValid()) { myLine = getDocument().getLineNumber(getStartOffset()); int endLine = getDocument().getLineNumber(getEndOffset()); if (endLine != myLine) { setIntervalEnd(getDocument().getLineEndOffset(myLine)); } } } if (isValid() && getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE) { setIntervalStart(DocumentUtil.getFirstNonSpaceCharOffset(getDocument(), myLine)); setIntervalEnd(getDocument().getLineEndOffset(myLine)); } }
private int visualLineStartOffset(int offset, boolean leanForward) { EditorImpl editor = myView.getEditor(); offset = DocumentUtil.alignToCodePointBoundary(myDocument, offset); int result = EditorUtil.getNotFoldedLineStartOffset(editor, offset); SoftWrapModelImpl softWrapModel = editor.getSoftWrapModel(); List<? extends SoftWrap> softWraps = softWrapModel.getRegisteredSoftWraps(); int currentOrPrevWrapIndex = softWrapModel.getSoftWrapIndex(offset); SoftWrap currentOrPrevWrap; if (currentOrPrevWrapIndex < 0) { currentOrPrevWrapIndex = - currentOrPrevWrapIndex - 2; currentOrPrevWrap = currentOrPrevWrapIndex < 0 || currentOrPrevWrapIndex >= softWraps.size() ? null : softWraps.get(currentOrPrevWrapIndex); } else { currentOrPrevWrap = leanForward ? softWraps.get(currentOrPrevWrapIndex) : null; } if (currentOrPrevWrap != null && currentOrPrevWrap.getStart() > result) { result = currentOrPrevWrap.getStart(); } return result; }
private static int calcOffset(@Nonnull Document document, int column, int startColumn, int startOffset, int endOffset, int tabSize) { int currentColumn = startColumn; CharSequence text = document.getImmutableCharSequence(); for (int i = startOffset; i < endOffset; i++) { if (text.charAt(i) == '\t') { currentColumn = (currentColumn / tabSize + 1) * tabSize; } else if (DocumentUtil.isSurrogatePair(document, i)) { if (currentColumn == column) return i; } else { currentColumn++; } if (currentColumn > column) return i; } return endOffset; }
@Override protected void changedUpdateImpl(@Nonnull DocumentEvent e) { super.changedUpdateImpl(e); if (isValid()) { int startOffset = intervalStart(); int endOffset = intervalEnd(); if (DocumentUtil.isInsideSurrogatePair(getDocument(), startOffset)) setIntervalStart(startOffset - 1); if (DocumentUtil.isInsideSurrogatePair(getDocument(), endOffset)) setIntervalStart(endOffset - 1); } if (endVirtualOffset > 0 && isValid()) { Document document = e.getDocument(); int startAfter = intervalStart(); int endAfter = intervalEnd(); if (!DocumentUtil.isAtLineEnd(endAfter, document) || document.getLineNumber(startAfter) != document.getLineNumber(endAfter)) { resetVirtualSelection(); } } }
@TestOnly public void validateState() { Document document = myEditor.getDocument(); if (myEditor.getDocument().isInBulkUpdate()) return; FoldingModel foldingModel = myEditor.getFoldingModel(); List<? extends SoftWrap> softWraps = getRegisteredSoftWraps(); int lastSoftWrapOffset = -1; for (SoftWrap wrap : softWraps) { int softWrapOffset = wrap.getStart(); LOG.assertTrue(softWrapOffset > lastSoftWrapOffset, "Soft wraps are not ordered"); LOG.assertTrue(softWrapOffset < document.getTextLength(), "Soft wrap is after document's end"); FoldRegion foldRegion = foldingModel.getCollapsedRegionAtOffset(softWrapOffset); LOG.assertTrue(foldRegion == null || foldRegion.getStartOffset() == softWrapOffset, "Soft wrap is inside fold region"); LOG.assertTrue(softWrapOffset != DocumentUtil.getLineEndOffset(softWrapOffset, document) || foldRegion != null, "Soft wrap before line break"); LOG.assertTrue(softWrapOffset != DocumentUtil.getLineStartOffset(softWrapOffset, document) || foldingModel.isOffsetCollapsed(softWrapOffset - 1), "Soft wrap after line break"); LOG.assertTrue(!DocumentUtil.isInsideSurrogatePair(document, softWrapOffset), "Soft wrap inside a surrogate pair"); lastSoftWrapOffset = softWrapOffset; } }
private void executeChanges(@Nonnull List<TemplateDocumentChange> changes) { if (isDisposed() || changes.isEmpty()) { return; } if (changes.size() > 1) { ContainerUtil.sort(changes, (o1, o2) -> { int startDiff = o2.startOffset - o1.startOffset; return startDiff != 0 ? startDiff : o2.endOffset - o1.endOffset; }); } DocumentUtil.executeInBulk(myDocument, true, () -> { for (TemplateDocumentChange change : changes) { replaceString(change.newValue, change.startOffset, change.endOffset, change.segmentNumber); } }); }
private void restoreEmptyVariables(IntArrayList indices) { List<TextRange> rangesToRemove = ContainerUtil.newArrayList(); for (int i = 0; i < indices.size(); i++) { int index = indices.get(i); rangesToRemove.add(TextRange.create(mySegments.getSegmentStart(index), mySegments.getSegmentEnd(index))); } Collections.sort(rangesToRemove, (o1, o2) -> { int startDiff = o2.getStartOffset() - o1.getStartOffset(); return startDiff != 0 ? startDiff : o2.getEndOffset() - o1.getEndOffset(); }); DocumentUtil.executeInBulk(myDocument, true, () -> { if (isDisposed()) { return; } for (TextRange range : rangesToRemove) { myDocument.deleteString(range.getStartOffset(), range.getEndOffset()); } }); }
public static Pair<Integer, Integer> getPlaceholderOffsets(@NotNull final AnswerPlaceholder answerPlaceholder, @NotNull final Document document) { int startOffset = answerPlaceholder.getOffset(); int delta = 0; final int length = answerPlaceholder.getRealLength(); int nonSpaceCharOffset = DocumentUtil.getFirstNonSpaceCharOffset(document, startOffset, startOffset + length); if (nonSpaceCharOffset != startOffset) { delta = startOffset - nonSpaceCharOffset; startOffset = nonSpaceCharOffset; } final int endOffset = startOffset + length + delta; return Pair.create(startOffset, endOffset); }
private void addPlaceholder(@NotNull CCState state) { Editor editor = state.getEditor(); Project project = state.getProject(); Document document = editor.getDocument(); FileDocumentManager.getInstance().saveDocument(document); final SelectionModel model = editor.getSelectionModel(); final int offset = model.hasSelection() ? model.getSelectionStart() : editor.getCaretModel().getOffset(); TaskFile taskFile = state.getTaskFile(); final Task task = state.getTaskFile().getTask(); int subtaskIndex = task instanceof TaskWithSubtasks ? ((TaskWithSubtasks)task).getActiveSubtaskIndex() : 0; final AnswerPlaceholder answerPlaceholder = new AnswerPlaceholder(); AnswerPlaceholderSubtaskInfo info = new AnswerPlaceholderSubtaskInfo(); answerPlaceholder.getSubtaskInfos().put(subtaskIndex, info); int index = taskFile.getAnswerPlaceholders().size(); answerPlaceholder.setIndex(index); answerPlaceholder.setTaskFile(taskFile); taskFile.sortAnswerPlaceholders(); answerPlaceholder.setOffset(offset); answerPlaceholder.setUseLength(false); String defaultPlaceholderText = "type here"; CCCreateAnswerPlaceholderDialog dlg = createDialog(project, answerPlaceholder); if (!dlg.showAndGet()) { return; } String answerPlaceholderText = dlg.getTaskText(); answerPlaceholder.setPossibleAnswer(model.hasSelection() ? model.getSelectedText() : defaultPlaceholderText); answerPlaceholder.setTaskText(StringUtil.notNullize(answerPlaceholderText)); answerPlaceholder.setLength(StringUtil.notNullize(answerPlaceholderText).length()); answerPlaceholder.setHints(dlg.getHints()); if (!model.hasSelection()) { DocumentUtil.writeInRunUndoTransparentAction(() -> document.insertString(offset, defaultPlaceholderText)); } answerPlaceholder.setPossibleAnswer(model.hasSelection() ? model.getSelectedText() : defaultPlaceholderText); AddAction action = new AddAction(answerPlaceholder, taskFile, editor); EduUtils.runUndoableAction(project, "Add Answer Placeholder", action); }
private static Iterable<PsiElement> getLineElements(final PsiFile file, int lineNumber) { ApplicationManager.getApplication().assertReadAccessAllowed(); Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); if (document == null || lineNumber >= document.getLineCount()) { return EmptyIterable.getInstance(); } final TextRange lineRange = DocumentUtil.getLineTextRange(document, lineNumber); return new Iterable<PsiElement>() { @Override public Iterator<PsiElement> iterator() { return new Iterator<PsiElement>() { PsiElement myElement = DebuggerUtilsEx.findElementAt(file, lineRange.getStartOffset()); @Override public boolean hasNext() { return myElement != null; } @Override public PsiElement next() { PsiElement res = myElement; do { myElement = PsiTreeUtil.nextLeaf(myElement); if (myElement == null || myElement.getTextOffset() > lineRange.getEndOffset()) { myElement = null; break; } } while (myElement.getTextLength() == 0); return res; } @Override public void remove() {} }; } }; }
@Override public void handleInsert(InsertionContext context) { super.handleInsert(context); Project project = context.getProject(); Document document = context.getDocument(); int lineStartOffset = DocumentUtil.getLineStartOffset(context.getStartOffset(), document); PsiDocumentManager.getInstance(project).commitDocument(document); CodeStyleManager.getInstance(project).adjustLineIndent(context.getFile(), lineStartOffset); }
private static void invokeOnTheFlyImportOptimizer(@NotNull final Runnable runnable, @NotNull final PsiFile file) { final Project project = file.getProject(); final Document document = PsiDocumentManager.getInstance(project).getDocument(file); if (document == null) return; final long stamp = document.getModificationStamp(); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { if (project.isDisposed() || document.getModificationStamp() != stamp) return; //no need to optimize imports on the fly during undo/redo final UndoManager undoManager = UndoManager.getInstance(project); if (undoManager.isUndoInProgress() || undoManager.isRedoInProgress()) return; PsiDocumentManager.getInstance(project).commitAllDocuments(); String beforeText = file.getText(); final long oldStamp = document.getModificationStamp(); DocumentUtil.writeInRunUndoTransparentAction(runnable); if (oldStamp != document.getModificationStamp()) { String afterText = file.getText(); if (Comparing.strEqual(beforeText, afterText)) { LOG.error( LogMessageEx.createEvent("Import optimizer hasn't optimized any imports", file.getViewProvider().getVirtualFile().getPath(), AttachmentFactory.createAttachment(file.getViewProvider().getVirtualFile()))); } } } }); }
@CalledInAwt public final void run() { if (!makeWritable(myProject, myDocument)) { VirtualFile file = FileDocumentManager.getInstance().getFile(myDocument); LOG.warn("Document is read-only" + (file != null ? ": " + file.getPresentableName() : "")); return; } ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { @Override public void run() { if (myUnderBulkUpdate) { DocumentUtil.executeInBulk(myDocument, true, new Runnable() { @Override public void run() { execute(); } }); } else { execute(); } } }, myCommandName, myCommandGroupId, myConfirmationPolicy, myDocument); } }); }
@Override @NotNull public RangeHighlighter addLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes) { if (isNotValidLine(lineNumber)) { throw new IndexOutOfBoundsException("lineNumber:" + lineNumber + ". Must be in [0, " + (getDocument().getLineCount() - 1) + "]"); } int offset = DocumentUtil.getFirstNonSpaceCharOffset(getDocument(), lineNumber); return addRangeHighlighter(offset, offset, layer, textAttributes, HighlighterTargetArea.LINES_IN_RANGE); }
@Override @Nullable public RangeHighlighterEx addPersistentLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes) { if (isNotValidLine(lineNumber)) { return null; } int offset = DocumentUtil.getFirstNonSpaceCharOffset(getDocument(), lineNumber); return addRangeHighlighter(PersistentRangeHighlighterImpl.create(this, offset, layer, HighlighterTargetArea.LINES_IN_RANGE, textAttributes, false), null); }
/** * Finds the start offset of visual line at which given offset is located, not taking soft wraps into account. */ public static int getNotFoldedLineStartOffset(@NotNull Editor editor, int offset) { while(true) { offset = DocumentUtil.getLineStartOffset(offset, editor.getDocument()); FoldRegion foldRegion = editor.getFoldingModel().getCollapsedRegionAtOffset(offset - 1); if (foldRegion == null || foldRegion.getStartOffset() >= offset) { break; } offset = foldRegion.getStartOffset(); } return offset; }
private void addHighlighter() { adjustCounter(myEditor, 1); int line = mySourcePosition.getLine(); Document document = myEditor.getDocument(); if (line < 0 || line >= document.getLineCount()) return; //if (myNotTopFrame) { // myEditor.getSelectionModel().setSelection(document.getLineStartOffset(line), document.getLineEndOffset(line) + document.getLineSeparatorLength(line)); // return; //} if (myRangeHighlighter != null) return; EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); TextAttributes attributes = myNotTopFrame ? scheme.getAttributes(DebuggerColors.NOT_TOP_FRAME_ATTRIBUTES) : scheme.getAttributes(DebuggerColors.EXECUTIONPOINT_ATTRIBUTES); MarkupModel markupModel = DocumentMarkupModel.forDocument(document, myProject, true); if (mySourcePosition instanceof HighlighterProvider) { TextRange range = ((HighlighterProvider)mySourcePosition).getHighlightRange(); if (range != null) { TextRange lineRange = DocumentUtil.getLineTextRange(document, line); range = range.intersection(lineRange); if (range != null && !range.isEmpty() && !range.equals(lineRange)) { myRangeHighlighter = markupModel.addRangeHighlighter(range.getStartOffset(), range.getEndOffset(), DebuggerColors.EXECUTION_LINE_HIGHLIGHTERLAYER, attributes, HighlighterTargetArea.EXACT_RANGE); } } } if (myRangeHighlighter == null) { myRangeHighlighter = markupModel.addLineHighlighter(line, DebuggerColors.EXECUTION_LINE_HIGHLIGHTERLAYER, attributes); } myRangeHighlighter.putUserData(EXECUTION_POINT_HIGHLIGHTER_KEY, true); myRangeHighlighter.setGutterIconRenderer(myGutterIconRenderer); }
public void doDefaultCommenting(final Block block) { final Document document = block.editor.getDocument(); DocumentUtil.executeInBulk( document, block.endLine - block.startLine >= Registry.intValue("comment.by.line.bulk.lines.trigger"), new Runnable() { @Override public void run() { for (int line = block.endLine; line >= block.startLine; line--) { int offset = document.getLineStartOffset(line); commentLine(block, line, offset); } } }); }
private void doIndentCommenting(final Block block) { final Document document = block.editor.getDocument(); final CharSequence chars = document.getCharsSequence(); final FileType fileType = block.psiFile.getFileType(); final Indent minIndent = computeMinIndent(block.editor, block.psiFile, block.startLine, block.endLine, fileType); DocumentUtil.executeInBulk( document, block.endLine - block.startLine > Registry.intValue("comment.by.line.bulk.lines.trigger"), new Runnable() { @Override public void run() { for (int line = block.endLine; line >= block.startLine; line--) { int lineStart = document.getLineStartOffset(line); int offset = lineStart; final StringBuilder buffer = new StringBuilder(); while (true) { String space = buffer.toString(); Indent indent = myCodeStyleManager.getIndent(space, fileType); if (indent.isGreaterThan(minIndent) || indent.equals(minIndent)) break; char c = chars.charAt(offset); if (c != ' ' && c != '\t') { String newSpace = myCodeStyleManager.fillIndent(minIndent, fileType); document.replaceString(lineStart, offset, newSpace); offset = lineStart + newSpace.length(); break; } buffer.append(c); offset++; } commentLine(block, line, offset); } } }); }
private static void adjustLineIndent(PsiFile file, Document document, int startOffset, int endOffset, int line, Project project) { CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); if (startOffset == endOffset) { int lineStart = document.getLineStartOffset(line); if (codeStyleManager.isLineToBeIndented(file, lineStart)) { codeStyleManager.adjustLineIndent(file, lineStart); } } else { codeStyleManager.adjustLineIndent(file, new TextRange(DocumentUtil.getLineStartOffset(startOffset, document), endOffset)); } }
public void reset(final String usageText, final FileType fileType) { reinitViews(); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (myEditor.isDisposed()) return; DocumentUtil.writeInRunUndoTransparentAction(new Runnable() { @Override public void run() { configureByText(usageText, fileType); } }); } }); }
public void setInputText(@NotNull final String query) { DocumentUtil.writeInRunUndoTransparentAction(new Runnable() { @Override public void run() { myConsoleEditor.getDocument().setText(query); } }); }
private static void changeIndent(@NotNull ChangeIndentContext context, int newIndent) { int caretOffset = context.editor.getCaretModel().getOffset(); String newIndentString = new IndentInfo(0, newIndent, 0).generateNewWhiteSpace(context.getIndentOptions()); int start = context.document.getLineStartOffset(context.targetLine); int end = DocumentUtil.getFirstNonSpaceCharOffset(context.document, context.targetLine); context.editor.getDocument().replaceString(start, end, newIndentString); if (caretOffset > start && caretOffset < end) { context.editor.getCaretModel().moveToOffset(start + newIndentString.length()); } }