Location (@NotNull Project project, @NotNull VirtualFile virtualFile, int lineNum, int columnNum) { final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); if (psiFile == null) { return null; } if (lineNum <= 0) { return PsiLocation.fromPsiElement(psiFile); } final Document doc = PsiDocumentManager.getInstance(project).getDocument(psiFile); if (doc == null) { return null; } if (lineNum > doc.getLineCount()) { return PsiLocation.fromPsiElement(psiFile); } final int lineStartOffset = doc.getLineStartOffset(lineNum - 1); final int endOffset = doc.getLineEndOffset(lineNum - 1); int offset = Math.min(lineStartOffset + Math.max(columnNum - 1, 0), endOffset); PsiElement elementAtLine = null; while (offset <= endOffset) { elementAtLine = psiFile.findElementAt(offset); if (elementAtLine == null || isNonBlankLeafPsiElement(elementAtLine)) break; int length = elementAtLine.getTextLength(); offset += length > 1 ? length - 1 : 1; } if (elementAtLine instanceof PsiPlainText && offset > 0) { int offsetInPlainTextFile = offset; return new PsiLocation<>(project, (PsiPlainText)elementAtLine) { @Nullable @Override public OpenFileDescriptor getOpenFileDescriptor() { VirtualFile file = getVirtualFile(); return file != null ? new OpenFileDescriptor(getProject(), file, offsetInPlainTextFile) : null; } }; } return PsiLocation.fromPsiElement(project, elementAtLine != null ? elementAtLine : psiFile); }