How would I write to the input field of Stdin in Golang without inputting it?

Viewed 153

So I am new to low level stuff so pardon my ignorance. I am attempting to write a minimal shell. To that end I want to implement command history similar to bash or zsh where an up-arrow can bring the most recent command up and put it in your typing field without actually inputting it.

Currently I am reading input like follows:

for {
        // prompter
        promptColor.Printf(shellPrompt)

        // read string from STDIN until newline
        input, _ := reader.ReadString('\n')
        // convert CRLF to LF
        input = strings.Replace(input, "\n", "", -1)

        // read input tokens
        tokens := SplitString(input)

        // parse tokens and execute relevant command
        Parse(tokens)
    }

using bufio.Reader to read in. I looked and I cannot find a method of writing to that input.

2 Answers

Most packages that want to implement this behavior will use the GNU Readline library. Even the Bash shell is using (modified copy) of this readline library. Consider one of two options:

The first path will give you the battle-proof ReadLine library, but will require building the "C" code. You can decide based no your experience/constraints which path to go.

There is no "typing field" in a shell; there are no fields at all. There's just an input stream, an output stream, and an error stream. You don't want to write to your own stdin either, certainly not to solve this. The way a shell generally does this (regardless of language) is:

  • User presses up arrow, application goes into history mode
  • Shell erases whatever is at the prompt and replaces it with the previous command in the history, keeping track of the current history index
  • If the user presses enter in history mode, it takes the current history index, and reads the command from there instead of from stdin
Related