Added support for line editing in KDL.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23514 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -141,11 +141,61 @@ kputs(const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
insert_char_into_line(char* buffer, int32& position, int32& length, char c)
|
||||||
|
{
|
||||||
|
// make room for the new char in the buffer by moving the subsequent ones
|
||||||
|
if (position < length)
|
||||||
|
memmove(buffer + position + 1, buffer + position, length - position);
|
||||||
|
|
||||||
|
buffer[position++] = c;
|
||||||
|
length++;
|
||||||
|
|
||||||
|
// print the char
|
||||||
|
kputchar(c);
|
||||||
|
|
||||||
|
// print the rest of the line again, if necessary
|
||||||
|
if (position < length) {
|
||||||
|
for (int32 i = position; i < length; i++)
|
||||||
|
kputchar(buffer[i]);
|
||||||
|
|
||||||
|
// reposition the cursor
|
||||||
|
kprintf("\x1b[%ldD", length - position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_char_from_line(char* buffer, int32& position, int32& length)
|
||||||
|
{
|
||||||
|
if (position == length)
|
||||||
|
return;
|
||||||
|
|
||||||
|
length--;
|
||||||
|
|
||||||
|
if (position < length) {
|
||||||
|
// move the subsequent chars
|
||||||
|
memmove(buffer + position, buffer + position + 1, length - position);
|
||||||
|
|
||||||
|
// print the rest of the line again, if necessary
|
||||||
|
for (int32 i = position; i < length; i++)
|
||||||
|
kputchar(buffer[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// visually clear the last char
|
||||||
|
kputchar(' ');
|
||||||
|
|
||||||
|
// reposition the cursor
|
||||||
|
kprintf("\x1b[%ldD", length - position + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
read_line(char *buffer, int32 maxLength)
|
read_line(char *buffer, int32 maxLength)
|
||||||
{
|
{
|
||||||
int32 currentHistoryLine = sCurrentLine;
|
int32 currentHistoryLine = sCurrentLine;
|
||||||
int32 position = 0;
|
int32 position = 0;
|
||||||
|
int32 length = 0;
|
||||||
bool done = false;
|
bool done = false;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
@@ -161,16 +211,27 @@ read_line(char *buffer, int32 maxLength)
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
case '\n':
|
case '\n':
|
||||||
case '\r':
|
case '\r':
|
||||||
buffer[position++] = '\0';
|
buffer[length++] = '\0';
|
||||||
kputchar('\n');
|
kputchar('\n');
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
case 8: // backspace
|
case 8: // backspace
|
||||||
if (position > 0) {
|
if (position > 0) {
|
||||||
kputs("\x1b[1D"); // move to the left one
|
|
||||||
kputchar(' ');
|
|
||||||
kputs("\x1b[1D"); // move to the left one
|
kputs("\x1b[1D"); // move to the left one
|
||||||
position--;
|
position--;
|
||||||
|
remove_char_from_line(buffer, position, length);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x1f & 'K': // CTRL-K -- clear line after current position
|
||||||
|
if (position < length) {
|
||||||
|
// clear chars
|
||||||
|
for (int32 i = position; i < length; i++)
|
||||||
|
kputchar(' ');
|
||||||
|
|
||||||
|
// reposition cursor
|
||||||
|
kprintf("\x1b[%ldD", length - position);
|
||||||
|
|
||||||
|
length = position;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 27: // escape sequence
|
case 27: // escape sequence
|
||||||
@@ -181,14 +242,14 @@ read_line(char *buffer, int32 maxLength)
|
|||||||
}
|
}
|
||||||
c = readChar();
|
c = readChar();
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'C': // right arrow acts like space
|
case 'C': // right arrow
|
||||||
buffer[position++] = ' ';
|
if (position < length) {
|
||||||
kputchar(' ');
|
kputs("\x1b[1C"); // move to the right one
|
||||||
|
position++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'D': // left arrow acts like backspace
|
case 'D': // left arrow
|
||||||
if (position > 0) {
|
if (position > 0) {
|
||||||
kputs("\x1b[1D"); // move to the left one
|
|
||||||
kputchar(' ');
|
|
||||||
kputs("\x1b[1D"); // move to the left one
|
kputs("\x1b[1D"); // move to the left one
|
||||||
position--;
|
position--;
|
||||||
}
|
}
|
||||||
@@ -198,7 +259,7 @@ read_line(char *buffer, int32 maxLength)
|
|||||||
{
|
{
|
||||||
int32 historyLine = 0;
|
int32 historyLine = 0;
|
||||||
|
|
||||||
if (c == 65) {
|
if (c == 'A') {
|
||||||
// up arrow
|
// up arrow
|
||||||
historyLine = currentHistoryLine - 1;
|
historyLine = currentHistoryLine - 1;
|
||||||
if (historyLine < 0)
|
if (historyLine < 0)
|
||||||
@@ -223,11 +284,38 @@ read_line(char *buffer, int32 maxLength)
|
|||||||
kprintf("\x1b[%ldD", position); // move to beginning of line
|
kprintf("\x1b[%ldD", position); // move to beginning of line
|
||||||
|
|
||||||
strcpy(buffer, sLineBuffer[historyLine]);
|
strcpy(buffer, sLineBuffer[historyLine]);
|
||||||
position = strlen(buffer);
|
length = position = strlen(buffer);
|
||||||
kprintf("%s\x1b[K", buffer); // print the line and clear the rest
|
kprintf("%s\x1b[K", buffer); // print the line and clear the rest
|
||||||
currentHistoryLine = historyLine;
|
currentHistoryLine = historyLine;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'H': // home
|
||||||
|
{
|
||||||
|
if (position > 0) {
|
||||||
|
kprintf("\x1b[%ldD", position);
|
||||||
|
position = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'F': // end
|
||||||
|
{
|
||||||
|
if (position < length) {
|
||||||
|
kprintf("\x1b[%ldC", length - position);
|
||||||
|
position = length;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '3': // if "3~", it's DEL
|
||||||
|
{
|
||||||
|
c = readChar();
|
||||||
|
if (c != '~')
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (position < length)
|
||||||
|
remove_char_from_line(buffer, position, length);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -249,22 +337,20 @@ read_line(char *buffer, int32 maxLength)
|
|||||||
}
|
}
|
||||||
/* supposed to fall through */
|
/* supposed to fall through */
|
||||||
default:
|
default:
|
||||||
if (isprint(c)) {
|
if (isprint(c))
|
||||||
buffer[position++] = c;
|
insert_char_into_line(buffer, position, length, c);
|
||||||
kputchar(c);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (position >= maxLength - 2) {
|
if (length >= maxLength - 2) {
|
||||||
buffer[position++] = '\0';
|
buffer[length++] = '\0';
|
||||||
kputchar('\n');
|
kputchar('\n');
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return position;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user