v icon indicating copy to clipboard operation
v copied to clipboard

`read_line` displays the prompt message multiple times for strings ending with `\n`.

Open viniciusfdasilva opened this issue 1 year ago • 7 comments

Describe the bug

When I run the code with v from within a file, after executing the code, the message appears on the screen and waits for input. When I enter the input, the message reappears with each character I input.

I conducted several tests and concluded that this happens when a \n is inserted at the end of the message, as shown in the code:

With bug

import readline { read_line }

fn main()
{
        s := read_line("Prompt Message\n")!
        print("${s} \n")
}

No bug

import readline { read_line }

fn main()
{
        s := read_line("Prompt Message")!
        print("${s} \n")
}

Reproduction Steps

error

Expected Behavior

  • Prompt message showed once time

Current Behavior

error

Possible Solution

No response

Additional Information/Context

No response

V version

V full version: V 0.4.4 ed754cf.9560d53

Environment details (OS name and version, etc.)

OS: linux, Ubuntu 23.04

[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.

viniciusfdasilva avatar Jan 17 '24 01:01 viniciusfdasilva

It repeats the prompt for every character you type, as you type them.

JalonSolov avatar Jan 17 '24 01:01 JalonSolov

@JalonSolov

Yes! And it's strange because without the \n it doesn't have this behavior!

viniciusfdasilva avatar Jan 17 '24 02:01 viniciusfdasilva

Not so strange, depending on how it was written. A "common" way to do it would be to move the cursor to the start of the line, and re-print the prompt + the char you typed. But if the prompt has \n, it will force it to the next line every time. I don't know if that's how the V version was done, but I have seen it before.

JalonSolov avatar Jan 17 '24 02:01 JalonSolov

@JalonSolov

Sure! In my case, I hadn't seen it happen before! That's why I found it strange! So can we consider that there is no bug in the implementation? Who would be able to say? Because I really don't know if this is the intended behavior of the implementation, and since I've never seen this case happen, I opened this issue to report it!

viniciusfdasilva avatar Jan 17 '24 02:01 viniciusfdasilva

It's definitely a bug. Just need someone to dig into the code and fix it.

JalonSolov avatar Jan 17 '24 03:01 JalonSolov

I found where the issue is occurring! However, I haven't found the solution yet. Once I find it, I'll submit a pull request

The error occurs precisely because in the file, for example, readline_nix.c.v, the function read_line_utf8(prompt string) ![]rune executes the following code:

for {
		flush_stdout()
		c := r.read_char() or { return err }
		a := r.analyse(c)
		if r.execute(a, c) {
			break
		}
	}

This for loop waits until the user enters \n to conclude the capture of the input. However, the r.execute function, while the value is different from \n and \r, also calls the r.refresh_line() function to add a new character.

And this r.refresh_line() function also prints to the prompt!

As a result, every time the user enters a character, the r.refresh_line() function is called and prints to the prompt!

To solve this, one could remove this print statement, but it's unclear if it might be necessary for other calls. I am still evaluating this before proposing a solution!

viniciusfdasilva avatar Jan 17 '24 04:01 viniciusfdasilva

Right. Check both with & without \n in the prompt, and even with multiple \n's in the prompt.

JalonSolov avatar Jan 17 '24 13:01 JalonSolov