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 ''
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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"
|
||||
// This is simplified implementation. if you need specification compliant 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.
|
||||
pub fn (r Readline) read_char() int {
|
||||
return utf8_getchar()
|
||||
pub fn (r Readline) read_char() !int {
|
||||
return int(term.utf8_getchar() or { return err })
|
||||
}
|
||||
|
||||
// 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)
|
||||
for {
|
||||
unsafe { C.fflush(C.stdout) }
|
||||
c := r.read_char()
|
||||
c := r.read_char() or { return err }
|
||||
a := r.analyse(c)
|
||||
if r.execute(a, c) {
|
||||
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`.
|
||||
fn (r Readline) analyse_control() Action {
|
||||
c := r.read_char()
|
||||
c := r.read_char() or { panic('Control sequence incomplete') }
|
||||
match u8(c) {
|
||||
`[` {
|
||||
sequence := r.read_char()
|
||||
sequence := r.read_char() or { panic('Control sequence incomplete') }
|
||||
match u8(sequence) {
|
||||
`C` { return .move_cursor_right }
|
||||
`D` { return .move_cursor_left }
|
||||
`B` { return .history_next }
|
||||
`A` { return .history_previous }
|
||||
`H` { return .move_cursor_begining }
|
||||
`F` { return .move_cursor_end }
|
||||
`1` { return r.analyse_extended_control() }
|
||||
`2`, `3` { return r.analyse_extended_control_no_eat(u8(sequence)) }
|
||||
else {}
|
||||
@ -259,7 +261,7 @@ fn (r Readline) analyse_control() Action {
|
||||
//TODO
|
||||
match c {
|
||||
case `[`:
|
||||
sequence := r.read_char()
|
||||
sequence := r.read_char()?
|
||||
match sequence {
|
||||
case `C`: return .move_cursor_right
|
||||
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 specialises in cursor control.
|
||||
fn (r Readline) analyse_extended_control() Action {
|
||||
r.read_char() // Removes ;
|
||||
c := r.read_char()
|
||||
r.read_char() or { panic('Control sequence incomplete') } // Removes ;
|
||||
c := r.read_char() or { panic('Control sequence incomplete') }
|
||||
match u8(c) {
|
||||
`5` {
|
||||
direction := r.read_char()
|
||||
direction := r.read_char() or { panic('Control sequence incomplete') }
|
||||
match u8(direction) {
|
||||
`C` { return .move_cursor_word_right }
|
||||
`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 specialises in detection of delete and insert keys.
|
||||
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 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