下面列出了com.intellij.psi.PsiWhiteSpace#com.intellij.openapi.editor.Document 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Nonnull
public DocumentEx getLastCommittedDocument(@Nonnull Document document) {
if (document instanceof FrozenDocument) return (DocumentEx)document;
if (document instanceof DocumentWindow) {
DocumentWindow window = (DocumentWindow)document;
Document delegate = window.getDelegate();
if (delegate instanceof FrozenDocument) return (DocumentEx)window;
if (!window.isValid()) {
throw new AssertionError("host committed: " + isCommitted(delegate) + ", window=" + window);
}
UncommittedInfo info = myUncommittedInfos.get(delegate);
DocumentWindow answer = info == null ? null : info.myFrozenWindows.get(document);
if (answer == null) answer = freezeWindow(window);
if (info != null) answer = ConcurrencyUtil.cacheOrGet(info.myFrozenWindows, window, answer);
return (DocumentEx)answer;
}
assert document instanceof DocumentImpl;
UncommittedInfo info = myUncommittedInfos.get(document);
return info != null ? info.myFrozen : ((DocumentImpl)document).freeze();
}
@Override
public IDoc getDocument(IFile virtualFile) {
if (virtualFile == null) {
return null;
}
Document document;
try {
document = FileDocumentManager.getInstance().getDocument(((FileImpl) virtualFile).virtualFile);
} catch (RuntimeException e) {
// We've seen an java.io.EOFException here before.
Flog.error(e);
return null;
}
if (document == null) {
return null;
}
return new DocImpl(context, document);
}
@Override
public boolean execute(EventData data) {
ProgressIndicator indicator = data.getIndicator();
int size = data.getSize();
int totalProcessed = 0;
StringBuilder marks = new StringBuilder();
for (Map.Entry<Document, List<MarkdownImage>> imageEntry : data.getWaitingProcessMap().entrySet()) {
int totalCount = imageEntry.getValue().size();
for (MarkdownImage markdownImage : imageEntry.getValue()) {
String imageName = markdownImage.getImageName();
indicator.setText2("Processing " + imageName);
marks.append(markdownImage.getFinalMark()).append(ImageContents.LINE_BREAK);
indicator.setFraction(((++totalProcessed * 1.0) + data.getIndex() * size) / totalCount * size);
}
}
ImageUtils.setStringToClipboard(marks.toString());
return true;
}
@Nullable
@Override
public SMTestLocator getTestLocator() {
return (protocol, path, project, globalSearchScope) -> {
try {
String[] fileInfo = path.split(Constants.SPEC_SCENARIO_DELIMITER);
VirtualFile file = LocalFileSystem.getInstance().findFileByPath(fileInfo[0]);
if (file == null) return new ArrayList<>();
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
if (psiFile == null) return new ArrayList<>();
Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
if (document == null) return new ArrayList<>();
int line = Integer.parseInt(fileInfo[1]);
PsiElement element = psiFile.findElementAt(document.getLineStartOffset(line));
if (element == null) return new ArrayList<>();
return Collections.singletonList(new PsiLocation<>(element));
} catch (Exception e) {
return new ArrayList<>();
}
};
}
@Override
public void actionPerformed(AnActionEvent e) {
final Document document = myEditor.getDocument();
final VirtualFile file = FileDocumentManager.getInstance().getFile(document);
if (file != null) {
ReadonlyStatusHandler.getInstance(myFile.getProject()).ensureFilesWritable(file);
}
String selection = myEditor.getSelectionModel().getSelectedText(true);
if (selection != null) {
selection = selection.trim();
PsiDocumentManager.getInstance(myFile.getProject()).commitAllDocuments();
myTemplate.wrap(selection, new CustomTemplateCallback(myEditor, myFile));
}
}
@Override
@Nullable
public PsiFile getPsiFile(@Nonnull Document document) {
if (document instanceof DocumentWindow && !((DocumentWindow)document).isValid()) {
return null;
}
PsiFile psiFile = getCachedPsiFile(document);
if (psiFile != null) {
return ensureValidFile(psiFile, "Cached PSI");
}
final VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document);
if (virtualFile == null || !virtualFile.isValid()) return null;
psiFile = getPsiFile(virtualFile);
if (psiFile == null) return null;
fireFileCreated(document, psiFile);
return psiFile;
}
/**
* 获取 VirtualFile 的几种方式
*
* @param e the e
*/
private void getVirtualFile(AnActionEvent e) {
// 获取 VirtualFile 方式一:
VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE);
// 获取多个 VirtualFile
VirtualFile[] virtualFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
// 方式二: 从本地文件系统路径获取
VirtualFile virtualFileFromLocalFileSystem = LocalFileSystem.getInstance().findFileByIoFile(new File("path"));
// 方式三: 从 PSI 文件 (如果 PSI 文件仅存在内存中, 则可能返回 null)
PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);
if (psiFile != null) {
psiFile.getVirtualFile();
}
// 方式四: 从 document 中
Document document = Objects.requireNonNull(e.getData(PlatformDataKeys.EDITOR)).getDocument();
VirtualFile virtualFileFromDocument = FileDocumentManager.getInstance().getFile(document);
// 获取 document
getDocument(e);
}
public void apply(@javax.annotation.Nullable Project project, @Nonnull Document document) {
MarkupModel model = DocumentMarkupModel.forDocument(document, project, true);
for (Element piece : myPieces) {
RangeHighlighterEx delegate = piece.getDelegate();
if (!delegate.isValid()) continue;
RangeHighlighter highlighter = model
.addRangeHighlighter(piece.getStart(), piece.getEnd(), delegate.getLayer(), delegate.getTextAttributes(), delegate.getTargetArea());
highlighter.setEditorFilter(delegate.getEditorFilter());
highlighter.setCustomRenderer(delegate.getCustomRenderer());
highlighter.setErrorStripeMarkColor(delegate.getErrorStripeMarkColor());
highlighter.setErrorStripeTooltip(delegate.getErrorStripeTooltip());
highlighter.setGutterIconRenderer(delegate.getGutterIconRenderer());
highlighter.setLineMarkerRenderer(delegate.getLineMarkerRenderer());
highlighter.setLineSeparatorColor(delegate.getLineSeparatorColor());
highlighter.setThinErrorStripeMark(delegate.isThinErrorStripeMark());
highlighter.setLineSeparatorPlacement(delegate.getLineSeparatorPlacement());
highlighter.setLineSeparatorRenderer(delegate.getLineSeparatorRenderer());
}
}
@Nullable
public Runnable startNonCustomTemplates(final Map<TemplateImpl, String> template2argument, final Editor editor, @Nullable final PairProcessor<String, String> processor) {
final int caretOffset = editor.getCaretModel().getOffset();
final Document document = editor.getDocument();
final CharSequence text = document.getCharsSequence();
if (template2argument == null || template2argument.isEmpty()) {
return null;
}
return () -> {
if (template2argument.size() == 1) {
TemplateImpl template = template2argument.keySet().iterator().next();
String argument = template2argument.get(template);
int templateStart = getTemplateStart(template, argument, caretOffset, text);
startTemplateWithPrefix(editor, template, templateStart, processor, argument);
}
else {
ListTemplatesHandler.showTemplatesLookup(myProject, editor, template2argument);
}
};
}
@Nonnull
private TextChunk[] initChunks() {
PsiFile psiFile = getPsiFile();
Document document = psiFile == null ? null : PsiDocumentManager.getInstance(getProject()).getDocument(psiFile);
TextChunk[] chunks;
if (document == null) {
// element over light virtual file
PsiElement element = getElement();
if (element == null) {
chunks = new TextChunk[]{new TextChunk(SimpleTextAttributes.ERROR_ATTRIBUTES.toTextAttributes(), UsageViewBundle.message("node.invalid"))};
}
else {
chunks = new TextChunk[]{new TextChunk(new TextAttributes(), element.getText())};
}
}
else {
chunks = ChunkExtractor.extractChunks(psiFile, this);
}
myTextChunks = new SoftReference<>(chunks);
return chunks;
}
@SuppressWarnings({"UNUSED_SYMBOL"})
private void restoreFileContent(final PsiFile file, final String text) {
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(file);
document.replaceString(0, document.getTextLength(), text);
PsiDocumentManager.getInstance(getProject()).commitDocument(document);
}
});
}
}, "test", null);
}
private void formatInternal(PsiFile file, Collection<TextRange> ranges) {
ApplicationManager.getApplication().assertWriteAccessAllowed();
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject());
documentManager.commitAllDocuments();
CheckUtil.checkWritable(file);
Document document = documentManager.getDocument(file);
if (document == null) {
return;
}
// If there are postponed PSI changes (e.g., during a refactoring), just abort.
// If we apply them now, then the incoming text ranges may no longer be valid.
if (documentManager.isDocumentBlockedByPsi(document)) {
return;
}
format(file, document, ranges);
}
final void rebuildStub() {
ApplicationManager.getApplication().invokeLater(() -> {
if (!myManager.isDisposed()) {
myManager.dropPsiCaches();
}
final VirtualFile vFile = getVirtualFile();
if (vFile != null && vFile.isValid()) {
final Document doc = FileDocumentManager.getInstance().getCachedDocument(vFile);
if (doc != null) {
FileDocumentManager.getInstance().saveDocument(doc);
}
FileContentUtilCore.reparseFiles(vFile);
StubTreeLoader.getInstance().rebuildStubTree(vFile);
}
}, ModalityState.NON_MODAL);
}
@Nullable
public ListPopup createPopup(@Nonnull DataContext dataContext) {
final VirtualFile virtualFile = dataContext.getData(CommonDataKeys.VIRTUAL_FILE);
if (virtualFile == null) return null;
boolean enabled = checkEnabled(virtualFile);
if (!enabled) return null;
Editor editor = dataContext.getData(CommonDataKeys.EDITOR);
FileDocumentManager documentManager = FileDocumentManager.getInstance();
final Document document = documentManager.getDocument(virtualFile);
if (!allowDirectories && virtualFile.isDirectory() || document == null && !virtualFile.isDirectory()) return null;
final byte[] bytes;
try {
bytes = virtualFile.isDirectory() ? null : VfsUtilCore.loadBytes(virtualFile);
}
catch (IOException e) {
return null;
}
DefaultActionGroup group = createActionGroup(virtualFile, editor, document, bytes, null);
return JBPopupFactory.getInstance().createActionGroupPopup(getTemplatePresentation().getText(), group, dataContext, JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false);
}
@Deprecated
//@ApiStatus.ScheduledForRemoval(inVersion = "2017")
// todo remove when plugins come to their senses and stopped using it
// todo to be removed in idea 17
public static void cachePsi(@Nonnull Document document, @Nullable PsiFile file) {
DeprecatedMethodException.report("Unsupported method");
}
WidgetIndentHitTester(List<WidgetIndentGuideDescriptor> descriptors, Document document) {
final int lineCount = document.getLineCount();
lines = new boolean[lineCount];
// TODO(jacobr): optimize using a more clever data structure.
for (WidgetIndentGuideDescriptor descriptor : descriptors) {
// if (descriptor.parent)
{
final int last = min(lines.length, descriptor.endLine + 1);
for (int i = max(descriptor.startLine - 1, 0); i < last; i++) {
lines[i] = true;
}
}
}
}
private static Document createDocument(CharSequence text, @Nullable Map<TemplateContextType, Boolean> context, Project project) {
if (context != null) {
for (Map.Entry<TemplateContextType, Boolean> entry : context.entrySet()) {
if (entry.getValue()) {
return entry.getKey().createDocument(text, project);
}
}
}
return EditorFactory.getInstance().createDocument(text);
}
private Document createDocument(final Project project, @Nonnull String text) {
final FileType fileType = PlainTextLanguage.INSTANCE.getAssociatedFileType();
assert fileType != null;
final long stamp = LocalTimeCounter.currentTime();
final PsiFile psiFile = PsiFileFactory.getInstance(project)
.createFileFromText("Dummy." + fileType.getDefaultExtension(), fileType, text, stamp, true, false);
psiFile.putUserData(COMPLETING_TEXT_FIELD_KEY, this);
final Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
assert document != null;
return document;
}
private static int normalize(Document document, int offset) {
if (offset < 0) {
return 0;
}
if (offset >= document.getTextLength()) {
return Math.max(document.getTextLength() - 1, 0);
}
return offset;
}
private static void insertNewLineSubstitutors(Document document, AtomicBoolean showMore, List<RangeMarker> lineSeparators) {
for (RangeMarker marker : lineSeparators) {
if (!marker.isValid()) {
showMore.set(true);
continue;
}
int offset = marker.getStartOffset();
if (offset == 0 || offset == document.getTextLength()) {
continue;
}
boolean spaceBefore = offset > 0 && Character.isWhitespace(document.getCharsSequence().charAt(offset - 1));
if (offset < document.getTextLength()) {
boolean spaceAfter = Character.isWhitespace(document.getCharsSequence().charAt(offset));
int next = CharArrayUtil.shiftForward(document.getCharsSequence(), offset, " \t");
if (next < document.getTextLength() && !Character.isLowerCase(document.getCharsSequence().charAt(next))) {
document.insertString(offset, (spaceBefore ? "" : " ") + "//" + (spaceAfter ? "" : " "));
continue;
}
if (spaceAfter) {
continue;
}
}
if (spaceBefore) {
continue;
}
document.insertString(offset, " ");
}
}
public static void addRunOnCommit(@Nonnull Document document, @Nonnull Runnable action) {
synchronized (ACTION_AFTER_COMMIT) {
List<Runnable> list = document.getUserData(ACTION_AFTER_COMMIT);
if (list == null) {
document.putUserData(ACTION_AFTER_COMMIT, list = new SmartList<>());
}
list.add(action);
}
}
private void checkNull(@Nonnull IElementType type, @Nullable MappedRange range) {
if (range != null) {
Document mainDocument = getDocument();
VirtualFile file = mainDocument == null ? null : FileDocumentManager.getInstance().getFile(mainDocument);
LOG.error("Expected null range on " + type + ", found " + range + "; highlighter=" + getSyntaxHighlighter(),
new Attachment(file != null ? file.getName() : "editorText.txt", myText.toString()));
}
}
public void testReplaceDocumentTextWithTheSameText() throws Exception {
final VirtualFile file = createFile();
final DocumentEx document = (DocumentEx)myDocumentManager.getDocument(file);
final String newText = "test text";
assertNotNull(file.toString(), document);
WriteCommandAction.runWriteCommandAction(myProject, new Runnable() {
@Override
public void run() {
document.replaceString(0, document.getTextLength(), newText);
assertTrue(myDocumentManager.isDocumentUnsaved(document));
myDocumentManager.saveDocument(document);
getProject().getMessageBus().connect(getTestRootDisposable()).subscribe(AppTopics.FILE_DOCUMENT_SYNC, new FileDocumentManagerAdapter() {
@Override
public void beforeDocumentSaving(@Nonnull Document documentToSave) {
assertNotSame(document, documentToSave);
}
});
final long modificationStamp = document.getModificationStamp();
document.replaceString(0, document.getTextLength(), newText);
if (myDocumentManager.isDocumentUnsaved(document)) {
assertTrue(document.getModificationStamp() > modificationStamp);
}
else {
assertEquals(modificationStamp, document.getModificationStamp());
}
}
});
}
public void testGetDocument_CreatesNewAfterGCed() throws Exception {
final VirtualFile file = createFile();
Document document = myDocumentManager.getDocument(file);
int idCode = System.identityHashCode(document);
//noinspection UnusedAssignment
document = null;
System.gc();
System.gc();
document = myDocumentManager.getDocument(file);
assertTrue(idCode != System.identityHashCode(document));
}
private static void adjustIndentationInRange(@Nonnull PsiFile file, @Nonnull Document document, @Nonnull TextRange[] indents, final int indentAdjustment) {
final CharSequence charsSequence = document.getCharsSequence();
for (final TextRange indent : indents) {
final String oldIndentStr = charsSequence.subSequence(indent.getStartOffset() + 1, indent.getEndOffset()).toString();
final int oldIndent = IndentHelperImpl.getIndent(file, oldIndentStr, true);
final String newIndentStr = IndentHelperImpl.fillIndent(CodeStyle.getIndentOptions(file), Math.max(oldIndent + indentAdjustment, 0));
document.replaceString(indent.getStartOffset() + 1, indent.getEndOffset(), newIndentStr);
}
}
void markFileScopeDirty(@Nonnull Document document, @Nonnull TextRange scope, int fileLength, @Nonnull @NonNls Object reason) {
assertAllowModifications();
log("Mark scope dirty: ", scope, reason);
synchronized (myDocumentToStatusMap) {
FileStatus status = myDocumentToStatusMap.get(document);
if (status == null) return; // all dirty already
if (status.defensivelyMarked) {
status.defensivelyMarked = false;
}
status.combineScopesWith(scope, fileLength, document);
}
}
private LineStatusTracker(@Nonnull final Project project,
@Nonnull final Document document,
@Nonnull final VirtualFile virtualFile,
@Nonnull final Mode mode) {
super(project, document);
myVirtualFile = virtualFile;
myMode = mode;
myFileEditorManager = FileEditorManager.getInstance(project);
myVcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(project);
}
@Override
void runFix(SoyAtParamSingle element) {
final Document document = getContainingDocument(element);
if (document == null) {
return;
}
SoyParamDefinitionIdentifier paramDefinitionIdentifier =
element.getParamDefinitionIdentifier();
if (paramDefinitionIdentifier == null) {
return;
}
deleteParamSpecifications(paramDefinitionIdentifier);
deleteElement(element, document);
}
private static void syncAcceptSlashR(Document originalDocument, Document documentCopy) {
if (!(originalDocument instanceof DocumentImpl) || !(documentCopy instanceof DocumentImpl)) {
return;
}
((DocumentImpl)documentCopy).setAcceptSlashR(((DocumentImpl)originalDocument).acceptsSlashR());
}
private boolean commitToExistingPsi(@Nonnull Document document,
@Nonnull List<? extends BooleanRunnable> finishProcessors,
@Nonnull List<? extends BooleanRunnable> reparseInjectedProcessors,
boolean synchronously,
@Nullable VirtualFile virtualFile) {
for (BooleanRunnable finishRunnable : finishProcessors) {
boolean success = finishRunnable.run();
if (synchronously) {
assert success : finishRunnable + " in " + finishProcessors;
}
if (!success) {
return false;
}
}
clearUncommittedInfo(document);
if (virtualFile != null) {
getSmartPointerManager().updatePointerTargetsAfterReparse(virtualFile);
}
FileViewProvider viewProvider = getCachedViewProvider(document);
if (viewProvider != null) {
viewProvider.contentsSynchronized();
}
for (BooleanRunnable runnable : reparseInjectedProcessors) {
if (!runnable.run()) return false;
}
return true;
}