1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-05-07 05:34:02 +02:00

Use full width of output panel for text

This commit is contained in:
Matt Ellis 2024-09-04 00:56:46 +01:00 committed by Alex Pláte
parent 10283ce2f8
commit 34fe09c8f9
5 changed files with 46 additions and 22 deletions
src/main/java/com/maddyhome/idea/vim/helper
vim-engine/src/main/kotlin/com/maddyhome/idea/vim

View File

@ -157,6 +157,19 @@ public class EditorHelper {
return (int)(getVisibleArea(editor).width / getPlainSpaceWidthFloat(editor));
}
/**
* Gets the number of characters that can be fit inside the output panel for an editor.
* <p>
* This will be greater than the approximate screen width as it also includes any gutter components in the editor.
* </p>
*
* @param editor The editor
* @return The approximate number of columns that can fit in the output panel
*/
public static int getApproximateOutputPanelWidth(final @NotNull Editor editor) {
return (int)(editor.getComponent().getWidth() / getPlainSpaceWidthFloat(editor));
}
/**
* Gets the width of the space character in the editor's plain font as a float.
* <p>
@ -273,7 +286,7 @@ public class EditorHelper {
// Scroll the given visual line to the caret location, but do not scroll down passed the end of file, or the current
// virtual space at the bottom of the screen
@NotNull final VimEditor editor1 = new IjVimEditor(editor);
final @NotNull VimEditor editor1 = new IjVimEditor(editor);
final int lastVisualLine = EngineEditorHelperKt.getVisualLineCount(editor1) - 1;
final int yBottomLineOffset = max(getOffsetToScrollVisualLineToBottomOfScreen(editor, lastVisualLine), visibleArea.y);
scrollVertically(editor, min(yVisualLine - caretScreenOffset - inlayOffset, yBottomLineOffset));
@ -325,7 +338,7 @@ public class EditorHelper {
final int lineHeight = editor.getLineHeight();
final int offset = y - ((screenHeight - lineHeight) / lineHeight / 2 * lineHeight);
@NotNull final VimEditor editor1 = new IjVimEditor(editor);
final @NotNull VimEditor editor1 = new IjVimEditor(editor);
final int lastVisualLine = EngineEditorHelperKt.getVisualLineCount(editor1) - 1;
final int offsetForLastLineAtBottom = getOffsetToScrollVisualLineToBottomOfScreen(editor, lastVisualLine);
@ -379,7 +392,7 @@ public class EditorHelper {
return 0;
}
private static int getHorizontalScrollbarHeight(@NotNull final Editor editor) {
private static int getHorizontalScrollbarHeight(final @NotNull Editor editor) {
// Horizontal scrollbars on macOS are either transparent AND auto-hide, so we don't need to worry about obscured
// text, or always visible, opaque and outside the content area, so we don't need to adjust for them
// Transparent scrollbars on Windows and Linux are overlays on the editor content area, and always visible. That
@ -462,7 +475,7 @@ public class EditorHelper {
*/
public static Pair<Boolean, Integer> scrollFullPageDown(final @NotNull Editor editor, int pages) {
final Rectangle visibleArea = getVisibleArea(editor);
@NotNull final VimEditor editor2 = new IjVimEditor(editor);
final @NotNull VimEditor editor2 = new IjVimEditor(editor);
final int lastVisualLine = EngineEditorHelperKt.getVisualLineCount(editor2) - 1;
int y = visibleArea.y + visibleArea.height;
@ -480,7 +493,7 @@ public class EditorHelper {
caretVisualLine = lastVisualLine;
}
else {
@NotNull final VimEditor editor1 = new IjVimEditor(editor);
final @NotNull VimEditor editor1 = new IjVimEditor(editor);
caretVisualLine = EngineEditorHelperKt.getVisualLineCount(editor1) - 1;
completed = false;
}
@ -515,7 +528,7 @@ public class EditorHelper {
public static Pair<Boolean, Integer> scrollFullPageUp(final @NotNull Editor editor, int pages) {
final Rectangle visibleArea = getVisibleArea(editor);
final int lineHeight = editor.getLineHeight();
@NotNull final VimEditor editor1 = new IjVimEditor(editor);
final @NotNull VimEditor editor1 = new IjVimEditor(editor);
final int lastVisualLine = EngineEditorHelperKt.getVisualLineCount(editor1) - 1;
int y = visibleArea.y;

View File

@ -13,7 +13,6 @@ import com.intellij.openapi.editor.ReadOnlyFragmentModificationException
import com.intellij.openapi.editor.VisualPosition
import com.intellij.openapi.editor.actionSystem.EditorActionManager
import com.intellij.openapi.editor.ex.util.EditorUtil
import com.maddyhome.idea.vim.api.EngineEditorHelper
import com.maddyhome.idea.vim.api.EngineEditorHelperBase
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.VimRangeMarker
@ -42,6 +41,10 @@ internal class IjEditorHelper : EngineEditorHelperBase() {
return EditorHelper.getApproximateScreenWidth(editor.ij)
}
override fun getApproximateOutputPanelWidth(editor: VimEditor): Int {
return EditorHelper.getApproximateOutputPanelWidth(editor.ij)
}
override fun handleWithReadonlyFragmentModificationHandler(editor: VimEditor, exception: Exception) {
return EditorActionManager.getInstance()
.getReadonlyFragmentModificationHandler(editor.ij.document)

View File

@ -18,7 +18,23 @@ interface EngineEditorHelper {
fun amountOfInlaysBeforeVisualPosition(editor: VimEditor, pos: VimVisualPosition): Int
fun getVisualLineAtTopOfScreen(editor: VimEditor): Int
fun getVisualLineAtBottomOfScreen(editor: VimEditor): Int
/**
* Return the approximate width, in columns, of the editor surface
*
* This is used for calculating the usable editor width, for editor features such as horizontal scrolling.
*/
fun getApproximateScreenWidth(editor: VimEditor): Int
/**
* Return the approximate width, in columns, of the output panel for a given editor
*
* This value is the approximate number of columns that can be displayed in the output panel for an editor. It will be
* greater than the value returned by [getApproximateScreenWidth], which is the number of editor columns in what Vim
* calls a "screen". That value does not include the space taken up by the editor gutter and other components, and if
* used for the output panel will leave a gap on the right-hand side of the panel.
*/
fun getApproximateOutputPanelWidth(editor: VimEditor): Int
fun handleWithReadonlyFragmentModificationHandler(editor: VimEditor, exception: java.lang.Exception)
fun pad(editor: VimEditor, line: Int, to: Int): String
fun inlayAwareOffsetToVisualPosition(editor: VimEditor, offset: Int): VimVisualPosition
@ -238,9 +254,7 @@ fun VimEditor.getText(range: TextRange): String {
val end = range.endOffsets[i]
val line = getText(start, end)
if (line.isEmpty()) {
for (j in 0 until max) {
res.append(' ')
}
repeat(max) { res.append(' ') }
} else {
res.append(line)
}
@ -307,4 +321,4 @@ interface VimRangeMarker {
val isValid: Boolean
fun dispose()
}
}

View File

@ -126,7 +126,7 @@ open class VimDigraphGroupBase() : VimDigraphGroup {
}
override fun showDigraphs(editor: VimEditor, showHeaders: Boolean) {
val width = injector.engineEditorHelper.getApproximateScreenWidth(editor).let { if (it < 10) 80 else it }
val width = injector.engineEditorHelper.getApproximateOutputPanelWidth(editor).let { if (it < 10) 80 else it }
// Vim's columns are 13 characters wide, but for some reason, they suddenly switch to 12. It makes no obvious sense,
// and it's a quirk too far to copy.

View File

@ -195,7 +195,7 @@ fun parseOptionLine(editor: VimEditor, context: ExecutionContext, args: String,
}
// Now show all options that were individually requested
if (toShow.size > 0) {
if (toShow.isNotEmpty()) {
showOptions(editor, context, toShow, scope, false, columnFormat)
}
@ -240,9 +240,7 @@ private fun showOptions(
if (columnFormat || optionAsString.length >= colWidth) extra.add(optionAsString) else cells.add(optionAsString)
}
// Note that this is the approximate width of the associated editor, not the ex output panel!
// It excludes gutter width, for example
val width = injector.engineEditorHelper.getApproximateScreenWidth(editor).let { if (it < 20) 80 else it }
val width = injector.engineEditorHelper.getApproximateOutputPanelWidth(editor).let { if (it < 20) 80 else it }
val colCount = width / colWidth
val height = ceil(cells.size.toDouble() / colCount.toDouble()).toInt()
@ -260,18 +258,14 @@ private fun showOptions(
for (c in 0 until colCount) {
val index = c * height + h
if (index < cells.size) {
val padLength = lengthAtStartOfLine + (c * colWidth) - length
for (i in 1..padLength) {
append(' ')
}
repeat(lengthAtStartOfLine + (c * colWidth) - length) { append(' ') }
append(cells[index])
}
}
appendLine()
}
// Add any lines that are too long to fit into columns. The panel will soft wrap text
// Add any lines that are too long to fit into columns. The panel will soft-wrap text
for (option in extra) {
appendLine(option)
}