mirror of https://github.com/adamdruppe/arsd.git
line getter initial impl
This commit is contained in:
parent
e017511fc2
commit
9797370ad6
302
terminal.d
302
terminal.d
|
@ -1272,9 +1272,7 @@ struct Terminal {
|
||||||
readTermcap();
|
readTermcap();
|
||||||
|
|
||||||
if(type == ConsoleOutputType.cellular) {
|
if(type == ConsoleOutputType.cellular) {
|
||||||
doTermcap("ti");
|
goCellular();
|
||||||
clear();
|
|
||||||
moveTo(0, 0, ForceOption.alwaysSend); // we need to know where the cursor is for some features to work, and moving it is easier than querying it
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(terminalInFamily("xterm", "rxvt", "screen", "tmux")) {
|
if(terminalInFamily("xterm", "rxvt", "screen", "tmux")) {
|
||||||
|
@ -1283,29 +1281,8 @@ struct Terminal {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXPERIMENTAL do not use yet
|
private void goCellular() {
|
||||||
Terminal alternateScreen() {
|
version(Win32Console) {
|
||||||
assert(this.type != ConsoleOutputType.cellular);
|
|
||||||
|
|
||||||
this.flush();
|
|
||||||
return Terminal(ConsoleOutputType.cellular);
|
|
||||||
}
|
|
||||||
|
|
||||||
version(Windows) {
|
|
||||||
HANDLE hConsole;
|
|
||||||
CONSOLE_SCREEN_BUFFER_INFO originalSbi;
|
|
||||||
}
|
|
||||||
|
|
||||||
version(Win32Console)
|
|
||||||
/// ditto
|
|
||||||
this(ConsoleOutputType type) {
|
|
||||||
_initialized = true;
|
|
||||||
createLock();
|
|
||||||
if(UseVtSequences) {
|
|
||||||
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
initializeVt();
|
|
||||||
} else {
|
|
||||||
if(type == ConsoleOutputType.cellular) {
|
|
||||||
hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, null, CONSOLE_TEXTMODE_BUFFER, null);
|
hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, null, CONSOLE_TEXTMODE_BUFFER, null);
|
||||||
if(hConsole == INVALID_HANDLE_VALUE) {
|
if(hConsole == INVALID_HANDLE_VALUE) {
|
||||||
import std.conv;
|
import std.conv;
|
||||||
|
@ -1333,6 +1310,69 @@ struct Terminal {
|
||||||
GetConsoleCursorInfo(hConsole, &originalCursorInfo);
|
GetConsoleCursorInfo(hConsole, &originalCursorInfo);
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
} else {
|
||||||
|
doTermcap("ti");
|
||||||
|
clear();
|
||||||
|
moveTo(0, 0, ForceOption.alwaysSend); // we need to know where the cursor is for some features to work, and moving it is easier than querying it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void goLinear() {
|
||||||
|
version(Win32Console) {
|
||||||
|
auto stdo = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
SetConsoleActiveScreenBuffer(stdo);
|
||||||
|
if(hConsole !is stdo)
|
||||||
|
CloseHandle(hConsole);
|
||||||
|
|
||||||
|
hConsole = stdo;
|
||||||
|
} else {
|
||||||
|
doTermcap("te");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConsoleOutputType originalType;
|
||||||
|
private bool typeChanged;
|
||||||
|
|
||||||
|
// EXPERIMENTAL do not use yet
|
||||||
|
/++
|
||||||
|
It is not valid to call this if you constructed with minimalProcessing.
|
||||||
|
+/
|
||||||
|
void enableAlternateScreen(bool active) {
|
||||||
|
assert(type != ConsoleOutputType.minimalProcessing);
|
||||||
|
|
||||||
|
if(active) {
|
||||||
|
if(type == ConsoleOutputType.cellular)
|
||||||
|
return; // already set
|
||||||
|
|
||||||
|
flush();
|
||||||
|
goCellular();
|
||||||
|
type = ConsoleOutputType.cellular;
|
||||||
|
} else {
|
||||||
|
if(type == ConsoleOutputType.linear)
|
||||||
|
return; // already set
|
||||||
|
|
||||||
|
flush();
|
||||||
|
goLinear();
|
||||||
|
type = ConsoleOutputType.linear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
version(Windows) {
|
||||||
|
HANDLE hConsole;
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO originalSbi;
|
||||||
|
}
|
||||||
|
|
||||||
|
version(Win32Console)
|
||||||
|
/// ditto
|
||||||
|
this(ConsoleOutputType type) {
|
||||||
|
_initialized = true;
|
||||||
|
createLock();
|
||||||
|
if(UseVtSequences) {
|
||||||
|
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
initializeVt();
|
||||||
|
} else {
|
||||||
|
if(type == ConsoleOutputType.cellular) {
|
||||||
|
goCellular();
|
||||||
} else {
|
} else {
|
||||||
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
}
|
}
|
||||||
|
@ -1384,7 +1424,7 @@ struct Terminal {
|
||||||
|
|
||||||
if(UseVtSequences) {
|
if(UseVtSequences) {
|
||||||
if(type == ConsoleOutputType.cellular) {
|
if(type == ConsoleOutputType.cellular) {
|
||||||
doTermcap("te");
|
goLinear();
|
||||||
}
|
}
|
||||||
version(TerminalDirectToEmulator) {
|
version(TerminalDirectToEmulator) {
|
||||||
if(usingDirectEmulator) {
|
if(usingDirectEmulator) {
|
||||||
|
@ -1425,10 +1465,7 @@ struct Terminal {
|
||||||
SetConsoleOutputCP(oldCp);
|
SetConsoleOutputCP(oldCp);
|
||||||
SetConsoleCP(oldCpIn);
|
SetConsoleCP(oldCpIn);
|
||||||
|
|
||||||
auto stdo = GetStdHandle(STD_OUTPUT_HANDLE);
|
goLinear();
|
||||||
SetConsoleActiveScreenBuffer(stdo);
|
|
||||||
if(hConsole !is stdo)
|
|
||||||
CloseHandle(hConsole);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
version(TerminalDirectToEmulator)
|
version(TerminalDirectToEmulator)
|
||||||
|
@ -5285,7 +5322,40 @@ class LineGetter {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insertMode = true;
|
bool insertMode = true;
|
||||||
bool multiLineMode = false;
|
|
||||||
|
private ConsoleOutputType original = cast(ConsoleOutputType) -1;
|
||||||
|
private bool multiLineModeOn = false;
|
||||||
|
private int startOfLineXOriginal;
|
||||||
|
private int startOfLineYOriginal;
|
||||||
|
void multiLineMode(bool on) {
|
||||||
|
if(original == -1) {
|
||||||
|
original = terminal.type;
|
||||||
|
startOfLineXOriginal = startOfLineX;
|
||||||
|
startOfLineYOriginal = startOfLineY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(on) {
|
||||||
|
terminal.enableAlternateScreen = true;
|
||||||
|
startOfLineX = 0;
|
||||||
|
startOfLineY = 0;
|
||||||
|
}
|
||||||
|
else if(original == ConsoleOutputType.linear) {
|
||||||
|
terminal.enableAlternateScreen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!on) {
|
||||||
|
startOfLineX = startOfLineXOriginal;
|
||||||
|
startOfLineY = startOfLineYOriginal;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiLineModeOn = on;
|
||||||
|
}
|
||||||
|
bool multiLineMode() { return multiLineModeOn; }
|
||||||
|
|
||||||
|
void toggleMultiLineMode() {
|
||||||
|
multiLineMode = !multiLineModeOn;
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
private dchar[] line;
|
private dchar[] line;
|
||||||
private int cursorPosition = 0;
|
private int cursorPosition = 0;
|
||||||
|
@ -5558,6 +5628,12 @@ class LineGetter {
|
||||||
|
|
||||||
written++;
|
written++;
|
||||||
lineLength--;
|
lineLength--;
|
||||||
|
|
||||||
|
if(lg.multiLineMode) {
|
||||||
|
if(ch == '\n') {
|
||||||
|
lineLength = lg.terminal.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawContent(T)(T towrite, int highlightBegin = 0, int highlightEnd = 0, bool inverted = false, int lineidx = -1) {
|
void drawContent(T)(T towrite, int highlightBegin = 0, int highlightEnd = 0, bool inverted = false, int lineidx = -1) {
|
||||||
|
@ -5571,8 +5647,14 @@ class LineGetter {
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(idx, dchar ch; towrite) {
|
foreach(idx, dchar ch; towrite) {
|
||||||
if(lineLength <= 0)
|
if(lineLength <= 0) {
|
||||||
|
if(lg.multiLineMode) {
|
||||||
|
if(ch == '\n')
|
||||||
|
lineLength = lg.terminal.width;
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
static if(is(T == dchar[])) {
|
static if(is(T == dchar[])) {
|
||||||
if(lineidx != -1 && colorChars == 0) {
|
if(lineidx != -1 && colorChars == 0) {
|
||||||
|
@ -5587,7 +5669,7 @@ class LineGetter {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(ch) {
|
switch(ch) {
|
||||||
case '\n': specialChar('n'); break;
|
case '\n': lg.multiLineMode ? regularChar('\n') : specialChar('n'); break;
|
||||||
case '\r': specialChar('r'); break;
|
case '\r': specialChar('r'); break;
|
||||||
case '\a': specialChar('a'); break;
|
case '\a': specialChar('a'); break;
|
||||||
case '\t': specialChar('t'); break;
|
case '\t': specialChar('t'); break;
|
||||||
|
@ -5666,6 +5748,7 @@ class LineGetter {
|
||||||
if(!cdi.populated)
|
if(!cdi.populated)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if(!multiLineMode) {
|
||||||
if(UseVtSequences && !_drawWidthMax) {
|
if(UseVtSequences && !_drawWidthMax) {
|
||||||
terminal.writeStringRaw("\033[K");
|
terminal.writeStringRaw("\033[K");
|
||||||
} else {
|
} else {
|
||||||
|
@ -5675,9 +5758,12 @@ class LineGetter {
|
||||||
terminal.write(" ");
|
terminal.write(" ");
|
||||||
lastDrawLength = cdi.written;
|
lastDrawLength = cdi.written;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if echoChar is null then we don't want to reflect the position at all
|
// if echoChar is null then we don't want to reflect the position at all
|
||||||
terminal.moveTo(startOfLineX + ((echoChar == 0) ? 0 : cdi.cursorPositionToDrawX) + promptLength, startOfLineY + cdi.cursorPositionToDrawY);
|
terminal.moveTo(startOfLineX + ((echoChar == 0) ? 0 : cdi.cursorPositionToDrawX) + promptLength, startOfLineY + cdi.cursorPositionToDrawY);
|
||||||
|
} else {
|
||||||
|
if(echoChar != 0)
|
||||||
|
terminal.moveTo(cdi.cursorPositionToDrawX, cdi.cursorPositionToDrawY);
|
||||||
|
}
|
||||||
endRedraw(); // make sure the cursor is turned back on
|
endRedraw(); // make sure the cursor is turned back on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5714,17 +5800,26 @@ class LineGetter {
|
||||||
}
|
}
|
||||||
terminal.moveTo(startOfLineX, startOfLineY);
|
terminal.moveTo(startOfLineX, startOfLineY);
|
||||||
|
|
||||||
|
if(multiLineMode)
|
||||||
|
terminal.clear();
|
||||||
|
|
||||||
Drawer drawer = Drawer(this);
|
Drawer drawer = Drawer(this);
|
||||||
|
|
||||||
drawer.lineLength = availableLineLength();
|
drawer.lineLength = availableLineLength();
|
||||||
if(drawer.lineLength < 0)
|
if(drawer.lineLength < 0)
|
||||||
throw new Exception("too narrow terminal to draw");
|
throw new Exception("too narrow terminal to draw");
|
||||||
|
|
||||||
|
if(!multiLineMode) {
|
||||||
terminal.color(promptColor, background);
|
terminal.color(promptColor, background);
|
||||||
terminal.write(prompt);
|
terminal.write(prompt);
|
||||||
terminal.color(regularForeground, background);
|
terminal.color(regularForeground, background);
|
||||||
|
}
|
||||||
|
|
||||||
auto towrite = line[horizontalScrollPosition .. $];
|
auto towrite = line[horizontalScrollPosition .. $];
|
||||||
|
if(multiLineMode) {
|
||||||
|
towrite = line[];
|
||||||
|
horizontalScrollPosition = 0; // FIXME
|
||||||
|
}
|
||||||
auto cursorPositionToDrawX = cursorPosition - horizontalScrollPosition;
|
auto cursorPositionToDrawX = cursorPosition - horizontalScrollPosition;
|
||||||
auto cursorPositionToDrawY = 0;
|
auto cursorPositionToDrawY = 0;
|
||||||
|
|
||||||
|
@ -5762,8 +5857,27 @@ class LineGetter {
|
||||||
CoreRedrawInfo cri;
|
CoreRedrawInfo cri;
|
||||||
cri.populated = true;
|
cri.populated = true;
|
||||||
cri.written = drawer.written;
|
cri.written = drawer.written;
|
||||||
|
if(multiLineMode) {
|
||||||
|
cursorPositionToDrawX = 0;
|
||||||
|
cursorPositionToDrawY = 0;
|
||||||
|
// would be better if it did this in the same drawing pass...
|
||||||
|
foreach(idx, dchar ch; line) {
|
||||||
|
if(idx == cursorPosition)
|
||||||
|
break;
|
||||||
|
if(ch == '\n') {
|
||||||
|
cursorPositionToDrawX = 0;
|
||||||
|
cursorPositionToDrawY++;
|
||||||
|
} else {
|
||||||
|
cursorPositionToDrawX++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cri.cursorPositionToDrawX = cursorPositionToDrawX;
|
cri.cursorPositionToDrawX = cursorPositionToDrawX;
|
||||||
cri.cursorPositionToDrawY = cursorPositionToDrawY;
|
cri.cursorPositionToDrawY = cursorPositionToDrawY;
|
||||||
|
} else {
|
||||||
|
cri.cursorPositionToDrawX = cursorPositionToDrawX;
|
||||||
|
cri.cursorPositionToDrawY = cursorPositionToDrawY;
|
||||||
|
}
|
||||||
|
|
||||||
return cri;
|
return cri;
|
||||||
}
|
}
|
||||||
|
@ -6064,6 +6178,88 @@ class LineGetter {
|
||||||
int selectionEnd = -1;
|
int selectionEnd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void backwardToNewline() {
|
||||||
|
while(cursorPosition && line[cursorPosition - 1] != '\n')
|
||||||
|
cursorPosition--;
|
||||||
|
phantomCursorX = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void forwardToNewLine() {
|
||||||
|
while(cursorPosition < line.length && line[cursorPosition] != '\n')
|
||||||
|
cursorPosition++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int phantomCursorX;
|
||||||
|
|
||||||
|
void lineBackward() {
|
||||||
|
int count;
|
||||||
|
while(cursorPosition && line[cursorPosition - 1] != '\n') {
|
||||||
|
cursorPosition--;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
if(count > phantomCursorX)
|
||||||
|
phantomCursorX = count;
|
||||||
|
|
||||||
|
if(cursorPosition == 0)
|
||||||
|
return;
|
||||||
|
cursorPosition--;
|
||||||
|
|
||||||
|
while(cursorPosition && line[cursorPosition - 1] != '\n') {
|
||||||
|
cursorPosition--;
|
||||||
|
}
|
||||||
|
|
||||||
|
count = phantomCursorX;
|
||||||
|
while(count) {
|
||||||
|
if(cursorPosition == line.length)
|
||||||
|
break;
|
||||||
|
if(line[cursorPosition] == '\n')
|
||||||
|
break;
|
||||||
|
cursorPosition++;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lineForward() {
|
||||||
|
int count;
|
||||||
|
|
||||||
|
// see where we are in the current line
|
||||||
|
auto beginPos = cursorPosition;
|
||||||
|
while(beginPos && line[beginPos - 1] != '\n') {
|
||||||
|
beginPos--;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(count > phantomCursorX)
|
||||||
|
phantomCursorX = count;
|
||||||
|
|
||||||
|
// get to the next line
|
||||||
|
while(cursorPosition < line.length && line[cursorPosition] != '\n') {
|
||||||
|
cursorPosition++;
|
||||||
|
}
|
||||||
|
if(cursorPosition == line.length)
|
||||||
|
return;
|
||||||
|
cursorPosition++;
|
||||||
|
|
||||||
|
// get to the same spot in this same line
|
||||||
|
count = phantomCursorX;
|
||||||
|
while(count) {
|
||||||
|
if(cursorPosition == line.length)
|
||||||
|
break;
|
||||||
|
if(line[cursorPosition] == '\n')
|
||||||
|
break;
|
||||||
|
cursorPosition++;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pageBackward() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void pageForward() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/++
|
/++
|
||||||
for integrating into another event loop
|
for integrating into another event loop
|
||||||
you can pass individual events to this and
|
you can pass individual events to this and
|
||||||
|
@ -6219,13 +6415,18 @@ class LineGetter {
|
||||||
|
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
phantomCursorX = 0;
|
||||||
break;
|
break;
|
||||||
case KeyboardEvent.Key.escape:
|
case KeyboardEvent.Key.escape:
|
||||||
justHitTab = justKilled = false;
|
justHitTab = justKilled = false;
|
||||||
|
if(multiLineMode)
|
||||||
|
multiLineMode = false;
|
||||||
|
else {
|
||||||
cursorPosition = 0;
|
cursorPosition = 0;
|
||||||
horizontalScrollPosition = 0;
|
horizontalScrollPosition = 0;
|
||||||
line = line[0 .. 0];
|
line = line[0 .. 0];
|
||||||
line.assumeSafeAppend();
|
line.assumeSafeAppend();
|
||||||
|
}
|
||||||
redraw();
|
redraw();
|
||||||
break;
|
break;
|
||||||
case KeyboardEvent.Key.F1:
|
case KeyboardEvent.Key.F1:
|
||||||
|
@ -6234,6 +6435,12 @@ class LineGetter {
|
||||||
break;
|
break;
|
||||||
case KeyboardEvent.Key.F2:
|
case KeyboardEvent.Key.F2:
|
||||||
justHitTab = justKilled = false;
|
justHitTab = justKilled = false;
|
||||||
|
|
||||||
|
if(ev.modifierState & ModifierState.control) {
|
||||||
|
toggleMultiLineMode();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
line[] &= cast(dchar) ~PRIVATE_BITS_MASK;
|
line[] &= cast(dchar) ~PRIVATE_BITS_MASK;
|
||||||
auto got = editLineInEditor(line, cursorPosition);
|
auto got = editLineInEditor(line, cursorPosition);
|
||||||
if(got !is null) {
|
if(got !is null) {
|
||||||
|
@ -6363,6 +6570,7 @@ class LineGetter {
|
||||||
break;
|
break;
|
||||||
case KeyboardEvent.Key.LeftArrow:
|
case KeyboardEvent.Key.LeftArrow:
|
||||||
justHitTab = justKilled = false;
|
justHitTab = justKilled = false;
|
||||||
|
phantomCursorX = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if(ev.modifierState & ModifierState.shift)
|
if(ev.modifierState & ModifierState.shift)
|
||||||
|
@ -6395,6 +6603,9 @@ class LineGetter {
|
||||||
goto default;
|
goto default;
|
||||||
case KeyboardEvent.Key.UpArrow:
|
case KeyboardEvent.Key.UpArrow:
|
||||||
justHitTab = justKilled = false;
|
justHitTab = justKilled = false;
|
||||||
|
if(multiLineMode)
|
||||||
|
lineBackward();
|
||||||
|
else
|
||||||
loadFromHistory(currentHistoryViewPosition + 1);
|
loadFromHistory(currentHistoryViewPosition + 1);
|
||||||
redraw();
|
redraw();
|
||||||
break;
|
break;
|
||||||
|
@ -6404,16 +6615,25 @@ class LineGetter {
|
||||||
goto default;
|
goto default;
|
||||||
case KeyboardEvent.Key.DownArrow:
|
case KeyboardEvent.Key.DownArrow:
|
||||||
justHitTab = justKilled = false;
|
justHitTab = justKilled = false;
|
||||||
|
if(multiLineMode)
|
||||||
|
lineForward();
|
||||||
|
else
|
||||||
loadFromHistory(currentHistoryViewPosition - 1);
|
loadFromHistory(currentHistoryViewPosition - 1);
|
||||||
redraw();
|
redraw();
|
||||||
break;
|
break;
|
||||||
case KeyboardEvent.Key.PageUp:
|
case KeyboardEvent.Key.PageUp:
|
||||||
justHitTab = justKilled = false;
|
justHitTab = justKilled = false;
|
||||||
|
if(multiLineMode)
|
||||||
|
pageBackward();
|
||||||
|
else
|
||||||
loadFromHistory(cast(int) history.length);
|
loadFromHistory(cast(int) history.length);
|
||||||
redraw();
|
redraw();
|
||||||
break;
|
break;
|
||||||
case KeyboardEvent.Key.PageDown:
|
case KeyboardEvent.Key.PageDown:
|
||||||
justHitTab = justKilled = false;
|
justHitTab = justKilled = false;
|
||||||
|
if(multiLineMode)
|
||||||
|
pageForward();
|
||||||
|
else
|
||||||
loadFromHistory(0);
|
loadFromHistory(0);
|
||||||
redraw();
|
redraw();
|
||||||
break;
|
break;
|
||||||
|
@ -6429,7 +6649,11 @@ class LineGetter {
|
||||||
goto case;
|
goto case;
|
||||||
case KeyboardEvent.Key.Home:
|
case KeyboardEvent.Key.Home:
|
||||||
justHitTab = justKilled = false;
|
justHitTab = justKilled = false;
|
||||||
|
if(multiLineMode) {
|
||||||
|
backwardToNewline();
|
||||||
|
} else {
|
||||||
cursorPosition = 0;
|
cursorPosition = 0;
|
||||||
|
}
|
||||||
horizontalScrollPosition = 0;
|
horizontalScrollPosition = 0;
|
||||||
redraw();
|
redraw();
|
||||||
break;
|
break;
|
||||||
|
@ -6439,8 +6663,12 @@ class LineGetter {
|
||||||
goto case;
|
goto case;
|
||||||
case KeyboardEvent.Key.End:
|
case KeyboardEvent.Key.End:
|
||||||
justHitTab = justKilled = false;
|
justHitTab = justKilled = false;
|
||||||
|
if(multiLineMode) {
|
||||||
|
forwardToNewLine();
|
||||||
|
} else {
|
||||||
cursorPosition = cast(int) line.length;
|
cursorPosition = cast(int) line.length;
|
||||||
scrollToEnd();
|
scrollToEnd();
|
||||||
|
}
|
||||||
redraw();
|
redraw();
|
||||||
break;
|
break;
|
||||||
case 'v', 22:
|
case 'v', 22:
|
||||||
|
@ -6679,6 +6907,10 @@ class LineGetter {
|
||||||
string finishGettingLine() {
|
string finishGettingLine() {
|
||||||
import std.conv;
|
import std.conv;
|
||||||
|
|
||||||
|
|
||||||
|
if(multiLineMode)
|
||||||
|
multiLineMode = false;
|
||||||
|
|
||||||
line[] &= cast(dchar) ~PRIVATE_BITS_MASK;
|
line[] &= cast(dchar) ~PRIVATE_BITS_MASK;
|
||||||
|
|
||||||
auto f = to!string(line);
|
auto f = to!string(line);
|
||||||
|
|
Loading…
Reference in New Issue