1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-03-04 21:32:52 +01:00

Use guicursor options to draw ex caret

This commit is contained in:
Matt Ellis 2021-06-29 01:30:19 +01:00
parent f05123123c
commit 64be75142e
No known key found for this signature in database
GPG Key ID: FA6025D54131324B
2 changed files with 40 additions and 27 deletions
src/com/maddyhome/idea/vim/ui/ex
test/org/jetbrains/plugins/ideavim/ex

View File

@ -28,6 +28,10 @@ import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.VimProjectService;
import com.maddyhome.idea.vim.group.HistoryGroup;
import com.maddyhome.idea.vim.helper.UiHelper;
import com.maddyhome.idea.vim.option.GuiCursorAttributes;
import com.maddyhome.idea.vim.option.GuiCursorMode;
import com.maddyhome.idea.vim.option.GuiCursorType;
import com.maddyhome.idea.vim.option.OptionsManager;
import kotlin.text.StringsKt;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@ -403,38 +407,25 @@ public class ExTextField extends JTextField {
// see :help 'guicursor'
// Note that we can't easily support guicursor because we don't have arbitrary control over the IntelliJ editor caret
private void setNormalModeCaret() {
caret.setBlockMode();
caret.setAttributes(OptionsManager.INSTANCE.getGuicursor().getAttributes(GuiCursorMode.CMD_LINE));
}
private void setInsertModeCaret() {
caret.setMode(CommandLineCaret.CaretMode.VER, 25);
caret.setAttributes(OptionsManager.INSTANCE.getGuicursor().getAttributes(GuiCursorMode.CMD_LINE_INSERT));
}
private void setReplaceModeCaret() {
caret.setMode(CommandLineCaret.CaretMode.HOR, 20);
caret.setAttributes(OptionsManager.INSTANCE.getGuicursor().getAttributes(GuiCursorMode.CMD_LINE_REPLACE));
}
private static class CommandLineCaret extends DefaultCaret {
private CaretMode mode;
private int blockPercentage = 100;
private GuiCursorType mode;
private int thickness = 100;
private int lastBlinkRate = 0;
private boolean hasFocus;
public enum CaretMode {
BLOCK,
VER,
HOR
}
void setBlockMode() {
setMode(CaretMode.BLOCK, 100);
}
void setMode(CaretMode mode, int blockPercentage) {
if (this.mode == mode && this.blockPercentage == blockPercentage) {
return;
}
public void setAttributes(GuiCursorAttributes attributes) {
// Hide the current caret and redraw without it. Then make the new caret visible, but only if it was already
// (logically) visible/active. Always making it visible can start the flasher timer unnecessarily.
@ -442,8 +433,8 @@ public class ExTextField extends JTextField {
if (isVisible()) {
setVisible(false);
}
this.mode = mode;
this.blockPercentage = blockPercentage;
mode = attributes.getType();
thickness = mode == GuiCursorType.BLOCK ? 100 : attributes.getThickness();
if (active) {
setVisible(true);
}
@ -500,7 +491,7 @@ public class ExTextField extends JTextField {
g.drawRect(r.x, r.y, r.width, r.height);
}
else {
r.setBounds(r.x, r.y, getCaretWidth(fm, blockPercentage), getBlockHeight(boundsHeight));
r.setBounds(r.x, r.y, getCaretWidth(fm, thickness), getBlockHeight(boundsHeight));
g.fillRect(r.x, r.y + boundsHeight - r.height, r.width, r.height);
}
}
@ -521,7 +512,7 @@ public class ExTextField extends JTextField {
height = blockHeight;
}
else {
width = this.getCaretWidth(fm, blockPercentage);
width = this.getCaretWidth(fm, thickness);
height = getBlockHeight(blockHeight);
}
x = r.x;
@ -531,7 +522,7 @@ public class ExTextField extends JTextField {
}
private int getCaretWidth(FontMetrics fm, int widthPercentage) {
if (mode == CaretMode.VER) {
if (mode == GuiCursorType.VER) {
// Don't show a proportional width of a proportional font
final int fullWidth = fm.charWidth('o');
return max(1, fullWidth * widthPercentage / 100);
@ -542,8 +533,8 @@ public class ExTextField extends JTextField {
}
private int getBlockHeight(int fullHeight) {
if (mode == CaretMode.HOR) {
return max(1, fullHeight * blockPercentage / 100);
if (mode == GuiCursorType.HOR) {
return max(1, fullHeight * thickness / 100);
}
return fullHeight;
}
@ -552,7 +543,7 @@ public class ExTextField extends JTextField {
@TestOnly
public @NonNls String getCaretShape() {
CommandLineCaret caret = (CommandLineCaret) getCaret();
return String.format("%s %d", caret.mode, caret.blockPercentage);
return String.format("%s %d", caret.mode, caret.thickness);
}
private Editor editor;

View File

@ -103,6 +103,28 @@ class ExEntryTest : VimTestCase() {
assertEquals("VER 25", exEntryPanel.entry.caretShape)
}
fun `test caret shape comes from guicursor`() {
enterCommand("set guicursor=c:ver50,ci:hor75,cr:block")
typeExInput(":")
assertEquals("VER 50", exEntryPanel.entry.caretShape)
typeText("set")
assertEquals("VER 50", exEntryPanel.entry.caretShape)
deactivateExEntry()
typeExInput(":set<Home>")
assertEquals("HOR 75", exEntryPanel.entry.caretShape)
deactivateExEntry()
typeExInput(":set<Home><Insert>")
assertEquals("BLOCK 100", exEntryPanel.entry.caretShape)
deactivateExEntry()
typeExInput(":set<Home><Insert><Insert>")
assertEquals("HOR 75", exEntryPanel.entry.caretShape)
}
fun `test move caret to beginning of line`() {
typeExInput(":set incsearch<C-B>")
assertExOffset(0)