Align output in scratch file

This commit is contained in:
Natalia Selezneva
2018-01-12 14:28:53 +03:00
parent 8e98f703ac
commit 0a274a7e61
@@ -40,14 +40,15 @@ import java.awt.Graphics
import java.awt.Rectangle import java.awt.Rectangle
object InlayScratchOutputHandler : ScratchOutputHandler { object InlayScratchOutputHandler : ScratchOutputHandler {
private const val maxInsertOffset = 60
private const val minSpaceCount = 4
override fun onStart(file: ScratchFile) { override fun onStart(file: ScratchFile) {
clear(file) clear(file)
} }
override fun handle(file: ScratchFile, expression: ScratchExpression, output: ScratchOutput) { override fun handle(file: ScratchFile, expression: ScratchExpression, output: ScratchOutput) {
val document = PsiDocumentManager.getInstance(file.psiFile.project).getDocument(file.psiFile) ?: return createInlay(file, expression.lineStart, output.text.substringBefore("\n"), output.type)
val lineEndOffset = document.getLineEndOffset(expression.lineStart)
createInlay(file.psiFile.project, file.psiFile.virtualFile, lineEndOffset, output.text.substringBefore("\n"), output.type)
if (output.type == ScratchOutputType.ERROR) { if (output.type == ScratchOutputType.ERROR) {
error(file, output.text) error(file, output.text)
@@ -67,30 +68,42 @@ object InlayScratchOutputHandler : ScratchOutputHandler {
ScratchToolWindow.clearToolWindow(file.psiFile.project) ScratchToolWindow.clearToolWindow(file.psiFile.project)
} }
private fun createInlay(project: Project, file: VirtualFile, offset: Int, inlayText: String, outputType: ScratchOutputType) { private fun createInlay(file: ScratchFile, line: Int, inlayText: String, outputType: ScratchOutputType) {
UIUtil.invokeLaterIfNeeded { UIUtil.invokeLaterIfNeeded {
val textEditor = FileEditorManager.getInstance(project).getSelectedEditor(file) as? TextEditor ?: return@invokeLaterIfNeeded val project = file.psiFile.project
val textEditor = FileEditorManager.getInstance(project).getSelectedEditor(file.psiFile.virtualFile) as? TextEditor ?: return@invokeLaterIfNeeded
val editor = textEditor.editor val editor = textEditor.editor
val text = editor.document.immutableCharSequence val lineStartOffset = editor.document.getLineStartOffset(line)
var insertOffset = offset val lineEndOffset = editor.document.getLineEndOffset(line)
while (insertOffset < text.length && Character.isJavaIdentifierPart(text[insertOffset])) insertOffset++ val lineLength = lineEndOffset - lineStartOffset
var spaceCount = maxLineLength(file) - lineLength + minSpaceCount
while(spaceCount + lineLength > maxInsertOffset && spaceCount > minSpaceCount) spaceCount--
val existing = editor.inlayModel val existing = editor.inlayModel
.getInlineElementsInRange(insertOffset, insertOffset) .getInlineElementsInRange(lineEndOffset, lineEndOffset)
.singleOrNull { it.renderer is ScratchFileRenderer } .singleOrNull { it.renderer is ScratchFileRenderer }
if (existing != null) { if (existing != null) {
existing.dispose() existing.dispose()
editor.inlayModel.addInlineElement( editor.inlayModel.addInlineElement(
insertOffset, lineEndOffset,
ScratchFileRenderer((existing.renderer as ScratchFileRenderer).text + "; " + inlayText, outputType) ScratchFileRenderer((existing.renderer as ScratchFileRenderer).text + "; " + inlayText, outputType)
) )
} else { } else {
editor.inlayModel.addInlineElement(insertOffset, ScratchFileRenderer(" $inlayText", outputType)) editor.inlayModel.addInlineElement(lineEndOffset, ScratchFileRenderer(" ".repeat(spaceCount) + inlayText, outputType))
} }
} }
} }
fun maxLineLength(file: ScratchFile): Int {
val doc = PsiDocumentManager.getInstance(file.psiFile.project).getDocument(file.psiFile) ?: return -1
return (0 until doc.lineCount)
.map { doc.getLineEndOffset(it) - doc.getLineStartOffset(it) }
.max()
?: -1
}
private fun clearInlays(project: Project, file: VirtualFile) { private fun clearInlays(project: Project, file: VirtualFile) {
UIUtil.invokeLaterIfNeeded { UIUtil.invokeLaterIfNeeded {
val editors = FileEditorManager.getInstance(project).getEditors(file) val editors = FileEditorManager.getInstance(project).getEditors(file)