mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
vrepl: add support for Home and End keys (#16116)
This commit is contained in:
parent
f8a28b5a5d
commit
a3b050aced
@ -57,30 +57,3 @@ pub fn string_from_wide2(_wstr &u16, len int) string {
|
|||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads an utf8 character from standard input
|
|
||||||
pub fn utf8_getchar() int {
|
|
||||||
c := C.getchar()
|
|
||||||
len := utf8_len(u8(~c))
|
|
||||||
if c < 0 {
|
|
||||||
return 0
|
|
||||||
} else if len == 0 {
|
|
||||||
return c
|
|
||||||
} else if len == 1 {
|
|
||||||
return -1
|
|
||||||
} else {
|
|
||||||
mut uc := c & ((1 << (7 - len)) - 1)
|
|
||||||
for i := 0; i + 1 < len; i++ {
|
|
||||||
c2 := C.getchar()
|
|
||||||
if c2 != -1 && (c2 >> 6) == 2 {
|
|
||||||
uc <<= 6
|
|
||||||
uc |= (c2 & 63)
|
|
||||||
} else if c2 == -1 {
|
|
||||||
return 0
|
|
||||||
} else {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return uc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -124,29 +124,6 @@ pub fn (_bytes []u8) utf8_to_utf32() ?rune {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate length to read from the first byte
|
|
||||||
fn utf8_len(c u8) int {
|
|
||||||
mut b := 0
|
|
||||||
mut x := c
|
|
||||||
if (x & 240) != 0 {
|
|
||||||
// 0xF0
|
|
||||||
x >>= 4
|
|
||||||
} else {
|
|
||||||
b += 4
|
|
||||||
}
|
|
||||||
if (x & 12) != 0 {
|
|
||||||
// 0x0C
|
|
||||||
x >>= 2
|
|
||||||
} else {
|
|
||||||
b += 2
|
|
||||||
}
|
|
||||||
if (x & 2) == 0 {
|
|
||||||
// 0x02
|
|
||||||
b++
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate string length for formatting, i.e. number of "characters"
|
// Calculate string length for formatting, i.e. number of "characters"
|
||||||
// This is simplified implementation. if you need specification compliant width,
|
// This is simplified implementation. if you need specification compliant width,
|
||||||
// use utf8.east_asian.display_width.
|
// use utf8.east_asian.display_width.
|
||||||
|
@ -122,8 +122,8 @@ pub fn (mut r Readline) disable_raw_mode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// read_char reads a single character.
|
// read_char reads a single character.
|
||||||
pub fn (r Readline) read_char() int {
|
pub fn (r Readline) read_char() !int {
|
||||||
return utf8_getchar()
|
return int(term.utf8_getchar() or { return err })
|
||||||
}
|
}
|
||||||
|
|
||||||
// read_line_utf8 blocks execution in a loop and awaits user input
|
// read_line_utf8 blocks execution in a loop and awaits user input
|
||||||
@ -151,7 +151,7 @@ pub fn (mut r Readline) read_line_utf8(prompt string) ?[]rune {
|
|||||||
print(r.prompt)
|
print(r.prompt)
|
||||||
for {
|
for {
|
||||||
unsafe { C.fflush(C.stdout) }
|
unsafe { C.fflush(C.stdout) }
|
||||||
c := r.read_char()
|
c := r.read_char() or { return err }
|
||||||
a := r.analyse(c)
|
a := r.analyse(c)
|
||||||
if r.execute(a, c) {
|
if r.execute(a, c) {
|
||||||
break
|
break
|
||||||
@ -239,15 +239,17 @@ fn (r Readline) analyse(c int) Action {
|
|||||||
|
|
||||||
// analyse_control returns an `Action` based on the type of input read by `read_char`.
|
// analyse_control returns an `Action` based on the type of input read by `read_char`.
|
||||||
fn (r Readline) analyse_control() Action {
|
fn (r Readline) analyse_control() Action {
|
||||||
c := r.read_char()
|
c := r.read_char() or { panic('Control sequence incomplete') }
|
||||||
match u8(c) {
|
match u8(c) {
|
||||||
`[` {
|
`[` {
|
||||||
sequence := r.read_char()
|
sequence := r.read_char() or { panic('Control sequence incomplete') }
|
||||||
match u8(sequence) {
|
match u8(sequence) {
|
||||||
`C` { return .move_cursor_right }
|
`C` { return .move_cursor_right }
|
||||||
`D` { return .move_cursor_left }
|
`D` { return .move_cursor_left }
|
||||||
`B` { return .history_next }
|
`B` { return .history_next }
|
||||||
`A` { return .history_previous }
|
`A` { return .history_previous }
|
||||||
|
`H` { return .move_cursor_begining }
|
||||||
|
`F` { return .move_cursor_end }
|
||||||
`1` { return r.analyse_extended_control() }
|
`1` { return r.analyse_extended_control() }
|
||||||
`2`, `3` { return r.analyse_extended_control_no_eat(u8(sequence)) }
|
`2`, `3` { return r.analyse_extended_control_no_eat(u8(sequence)) }
|
||||||
else {}
|
else {}
|
||||||
@ -259,7 +261,7 @@ fn (r Readline) analyse_control() Action {
|
|||||||
//TODO
|
//TODO
|
||||||
match c {
|
match c {
|
||||||
case `[`:
|
case `[`:
|
||||||
sequence := r.read_char()
|
sequence := r.read_char()?
|
||||||
match sequence {
|
match sequence {
|
||||||
case `C`: return .move_cursor_right
|
case `C`: return .move_cursor_right
|
||||||
case `D`: return .move_cursor_left
|
case `D`: return .move_cursor_left
|
||||||
@ -282,11 +284,11 @@ match c {
|
|||||||
// analyse_extended_control returns an `Action` based on the type of input read by `read_char`.
|
// analyse_extended_control returns an `Action` based on the type of input read by `read_char`.
|
||||||
// analyse_extended_control specialises in cursor control.
|
// analyse_extended_control specialises in cursor control.
|
||||||
fn (r Readline) analyse_extended_control() Action {
|
fn (r Readline) analyse_extended_control() Action {
|
||||||
r.read_char() // Removes ;
|
r.read_char() or { panic('Control sequence incomplete') } // Removes ;
|
||||||
c := r.read_char()
|
c := r.read_char() or { panic('Control sequence incomplete') }
|
||||||
match u8(c) {
|
match u8(c) {
|
||||||
`5` {
|
`5` {
|
||||||
direction := r.read_char()
|
direction := r.read_char() or { panic('Control sequence incomplete') }
|
||||||
match u8(direction) {
|
match u8(direction) {
|
||||||
`C` { return .move_cursor_word_right }
|
`C` { return .move_cursor_word_right }
|
||||||
`D` { return .move_cursor_word_left }
|
`D` { return .move_cursor_word_left }
|
||||||
@ -301,7 +303,7 @@ fn (r Readline) analyse_extended_control() Action {
|
|||||||
// analyse_extended_control_no_eat returns an `Action` based on the type of input byte given in `c`.
|
// analyse_extended_control_no_eat returns an `Action` based on the type of input byte given in `c`.
|
||||||
// analyse_extended_control_no_eat specialises in detection of delete and insert keys.
|
// analyse_extended_control_no_eat specialises in detection of delete and insert keys.
|
||||||
fn (r Readline) analyse_extended_control_no_eat(last_c u8) Action {
|
fn (r Readline) analyse_extended_control_no_eat(last_c u8) Action {
|
||||||
c := r.read_char()
|
c := r.read_char() or { panic('Control sequence incomplete') }
|
||||||
match u8(c) {
|
match u8(c) {
|
||||||
`~` {
|
`~` {
|
||||||
match last_c {
|
match last_c {
|
||||||
|
6
vlib/term/utf8.c.v
Normal file
6
vlib/term/utf8.c.v
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
module term
|
||||||
|
|
||||||
|
[inline]
|
||||||
|
fn getchar() int {
|
||||||
|
return C.getchar()
|
||||||
|
}
|
54
vlib/term/utf8.v
Normal file
54
vlib/term/utf8.v
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
module term
|
||||||
|
|
||||||
|
// utf8_getchar returns an utf8 rune from standard input
|
||||||
|
pub fn utf8_getchar() ?rune {
|
||||||
|
c := getchar()
|
||||||
|
if c == C.EOF {
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
len := utf8_len(u8(~c))
|
||||||
|
if c < 0 {
|
||||||
|
return 0
|
||||||
|
} else if len == 0 {
|
||||||
|
return c
|
||||||
|
} else if len == 1 {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
mut uc := c & ((1 << (7 - len)) - 1)
|
||||||
|
for i := 0; i + 1 < len; i++ {
|
||||||
|
c2 := getchar()
|
||||||
|
if c2 != -1 && (c2 >> 6) == 2 {
|
||||||
|
uc <<= 6
|
||||||
|
uc |= (c2 & 63)
|
||||||
|
} else if c2 == -1 {
|
||||||
|
return 0
|
||||||
|
} else {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// utf8_len calculates the length of a utf8 rune to read, according to its first byte
|
||||||
|
pub fn utf8_len(c u8) int {
|
||||||
|
mut b := 0
|
||||||
|
mut x := c
|
||||||
|
if (x & 240) != 0 {
|
||||||
|
// 0xF0
|
||||||
|
x >>= 4
|
||||||
|
} else {
|
||||||
|
b += 4
|
||||||
|
}
|
||||||
|
if (x & 12) != 0 {
|
||||||
|
// 0x0C
|
||||||
|
x >>= 2
|
||||||
|
} else {
|
||||||
|
b += 2
|
||||||
|
}
|
||||||
|
if (x & 2) == 0 {
|
||||||
|
// 0x02
|
||||||
|
b++
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user