mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
readline: utf8 compatibility
This commit is contained in:
parent
23c84516e2
commit
db44004d51
@ -35,12 +35,12 @@ struct Readline {
|
|||||||
mut:
|
mut:
|
||||||
is_raw bool
|
is_raw bool
|
||||||
orig_termios termios
|
orig_termios termios
|
||||||
current string // Line being edited
|
current ustring // Line being edited
|
||||||
cursor int // Cursor position
|
cursor int // Cursor position
|
||||||
overwrite bool
|
overwrite bool
|
||||||
cursor_row_offset int
|
cursor_row_offset int
|
||||||
prompt string
|
prompt string
|
||||||
previous_lines []string
|
previous_lines []ustring
|
||||||
search_index int
|
search_index int
|
||||||
is_tty bool
|
is_tty bool
|
||||||
}
|
}
|
||||||
@ -109,25 +109,24 @@ pub fn (r Readline) disable_raw_mode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read single char
|
// Read single char
|
||||||
// TODO: Maybe handle UNICODE
|
fn (r Readline) read_char() int {
|
||||||
fn (r Readline) read_char() byte {
|
return utf8_getchar()
|
||||||
return C.getchar()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main function of the readline module
|
// Main function of the readline module
|
||||||
// Will loop and ingest characters until EOF or Enter
|
// Will loop and ingest characters until EOF or Enter
|
||||||
// Returns the completed line
|
// Returns the completed line
|
||||||
pub fn (r mut Readline) read_line(prompt string) string {
|
pub fn (r mut Readline) read_line_utf8(prompt string) ustring {
|
||||||
r.current = ''
|
r.current = ''.ustring()
|
||||||
r.cursor = 0
|
r.cursor = 0
|
||||||
r.prompt = prompt
|
r.prompt = prompt
|
||||||
r.search_index = 0
|
r.search_index = 0
|
||||||
if r.previous_lines.len <= 1 {
|
if r.previous_lines.len <= 1 {
|
||||||
r.previous_lines << ''
|
r.previous_lines << ''.ustring()
|
||||||
r.previous_lines << ''
|
r.previous_lines << ''.ustring()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
r.previous_lines[0] = ''
|
r.previous_lines[0] = ''.ustring()
|
||||||
}
|
}
|
||||||
|
|
||||||
print(r.prompt)
|
print(r.prompt)
|
||||||
@ -138,11 +137,15 @@ pub fn (r mut Readline) read_line(prompt string) string {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r.previous_lines[0] = ''
|
r.previous_lines[0] = ''.ustring()
|
||||||
r.search_index = 0
|
r.search_index = 0
|
||||||
return r.current
|
return r.current
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (r mut Readline) read_line(prompt string) string {
|
||||||
|
return r.read_line_utf8(prompt).s
|
||||||
|
}
|
||||||
|
|
||||||
fn (r Readline) analyse(c byte) Action {
|
fn (r Readline) analyse(c byte) Action {
|
||||||
switch c {
|
switch c {
|
||||||
case `\0`: return Action.eof
|
case `\0`: return Action.eof
|
||||||
@ -206,7 +209,7 @@ fn (r Readline) analyse_extended_control_no_eat(last_c byte) Action {
|
|||||||
return Action.nothing
|
return Action.nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (r mut Readline) execute(a Action, c byte) bool {
|
fn (r mut Readline) execute(a Action, c int) bool {
|
||||||
switch a {
|
switch a {
|
||||||
case Action.eof: return r.eof()
|
case Action.eof: return r.eof()
|
||||||
case Action.insert_character: r.insert_character(c)
|
case Action.insert_character: r.insert_character(c)
|
||||||
@ -267,11 +270,10 @@ fn calculate_screen_position(x_in int, y_in int, screen_columns int, char_count
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Will redraw the line
|
// Will redraw the line
|
||||||
// TODO: Fix if prompt is longer than terminal columns
|
|
||||||
fn (r mut Readline) refresh_line() {
|
fn (r mut Readline) refresh_line() {
|
||||||
mut end_of_input := [0, 0]
|
mut end_of_input := [0, 0]
|
||||||
calculate_screen_position(r.prompt.len, 0, get_screen_columns(), r.current.len, mut end_of_input)
|
calculate_screen_position(r.prompt.len, 0, get_screen_columns(), r.current.len, mut end_of_input)
|
||||||
end_of_input[1] += r.current.count('\n')
|
end_of_input[1] += r.current.count('\n'.ustring())
|
||||||
mut cursor_pos := [0, 0]
|
mut cursor_pos := [0, 0]
|
||||||
calculate_screen_position(r.prompt.len, 0, get_screen_columns(), r.cursor, mut cursor_pos)
|
calculate_screen_position(r.prompt.len, 0, get_screen_columns(), r.cursor, mut cursor_pos)
|
||||||
|
|
||||||
@ -289,19 +291,16 @@ fn (r mut Readline) refresh_line() {
|
|||||||
// End the line without a newline
|
// End the line without a newline
|
||||||
fn (r mut Readline) eof() bool {
|
fn (r mut Readline) eof() bool {
|
||||||
r.previous_lines.insert(1, r.current)
|
r.previous_lines.insert(1, r.current)
|
||||||
|
r.cursor = r.current.len
|
||||||
|
r.refresh_line()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (r mut Readline) insert_character(c byte) {
|
fn (r mut Readline) insert_character(c int) {
|
||||||
// Small ASCII, to expand
|
|
||||||
if c >= 127 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// TODO: Add character if overwrite at end
|
|
||||||
if !r.overwrite || r.cursor == r.current.len {
|
if !r.overwrite || r.cursor == r.current.len {
|
||||||
r.current = r.current.left(r.cursor) + c.str() + r.current.right(r.cursor)
|
r.current = r.current.left(r.cursor).ustring() + utf32_to_str(u32(c)).ustring() + r.current.right(r.cursor).ustring()
|
||||||
} else {
|
} else {
|
||||||
r.current = r.current.left(r.cursor) + c.str() + r.current.right(r.cursor + 1)
|
r.current = r.current.left(r.cursor).ustring() + utf32_to_str(u32(c)).ustring() + r.current.right(r.cursor + 1).ustring()
|
||||||
}
|
}
|
||||||
r.cursor++
|
r.cursor++
|
||||||
// Refresh the line to add the new character
|
// Refresh the line to add the new character
|
||||||
@ -316,7 +315,7 @@ fn (r mut Readline) delete_character() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.cursor--
|
r.cursor--
|
||||||
r.current = r.current.left(r.cursor) + r.current.right(r.cursor + 1)
|
r.current = r.current.left(r.cursor).ustring() + r.current.right(r.cursor + 1).ustring()
|
||||||
r.refresh_line()
|
r.refresh_line()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,14 +324,17 @@ fn (r mut Readline) suppr_character() {
|
|||||||
if r.cursor > r.current.len {
|
if r.cursor > r.current.len {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.current = r.current.left(r.cursor) + r.current.right(r.cursor + 1)
|
r.current = r.current.left(r.cursor).ustring() + r.current.right(r.cursor + 1).ustring()
|
||||||
r.refresh_line()
|
r.refresh_line()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a line break then stops the main loop
|
// Add a line break then stops the main loop
|
||||||
fn (r mut Readline) commit_line() bool {
|
fn (r mut Readline) commit_line() bool {
|
||||||
r.previous_lines.insert(1, r.current)
|
r.previous_lines.insert(1, r.current)
|
||||||
r.current = r.current + '\n'
|
a := '\n'.ustring()
|
||||||
|
r.current = r.current + a
|
||||||
|
r.cursor = r.current.len
|
||||||
|
r.refresh_line()
|
||||||
if r.is_tty {
|
if r.is_tty {
|
||||||
println('')
|
println('')
|
||||||
}
|
}
|
||||||
@ -364,23 +366,23 @@ fn (r mut Readline) move_cursor_end() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the character is considered as a word-breaking character
|
// Check if the character is considered as a word-breaking character
|
||||||
fn (r Readline) is_break_character(c byte) bool {
|
fn (r Readline) is_break_character(c string) bool {
|
||||||
break_characters := ' \t\v\f\a\b\r\n`~!@#$%^&*()-=+[{]}\\|;:\'",<.>/?'
|
break_characters := ' \t\v\f\a\b\r\n`~!@#$%^&*()-=+[{]}\\|;:\'",<.>/?'
|
||||||
return break_characters.contains(c.str())
|
return break_characters.contains(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (r mut Readline) move_cursor_word_left() {
|
fn (r mut Readline) move_cursor_word_left() {
|
||||||
if r.cursor > 0 {
|
if r.cursor > 0 {
|
||||||
for ; r.cursor > 0 && r.is_break_character(r.current[r.cursor - 1]); r.cursor-- {}
|
for ; r.cursor > 0 && r.is_break_character(r.current.at(r.cursor - 1)); r.cursor-- {}
|
||||||
for ; r.cursor > 0 && !r.is_break_character(r.current[r.cursor - 1]); r.cursor-- {}
|
for ; r.cursor > 0 && !r.is_break_character(r.current.at(r.cursor - 1)); r.cursor-- {}
|
||||||
r.refresh_line()
|
r.refresh_line()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (r mut Readline) move_cursor_word_right() {
|
fn (r mut Readline) move_cursor_word_right() {
|
||||||
if r.cursor < r.current.len {
|
if r.cursor < r.current.len {
|
||||||
for ; r.cursor < r.current.len && r.is_break_character(r.current[r.cursor]); r.cursor++ {}
|
for ; r.cursor < r.current.len && r.is_break_character(r.current.at(r.cursor)); r.cursor++ {}
|
||||||
for ; r.cursor < r.current.len && !r.is_break_character(r.current[r.cursor]); r.cursor++ {}
|
for ; r.cursor < r.current.len && !r.is_break_character(r.current.at(r.cursor)); r.cursor++ {}
|
||||||
r.refresh_line()
|
r.refresh_line()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user