chzyer / readline

Readline is a pure go(golang) implementation for GNU-Readline kind library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

change of color (ANSI color code unchaged) when calling `log.SetOutput(l.Stderr())`

gekigek99 opened this issue · comments

example code:

package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"time"

	"github.com/chzyer/readline"
)

const (
	COLOR_RESET = "\033[0m"
	COLOR_GREEN = "\033[32m"
)

func main() {
	go logger()

	time.Sleep(2 * time.Second)

	fmt.Println("calling log.SetOutput() inside GetInput() which changes color")
	go GetInput()

	time.Sleep(time.Hour)
}

func logger() {
	for {
		log.Printf("%scolor%s\n", COLOR_GREEN, COLOR_RESET)
		time.Sleep(500 * time.Millisecond)
	}
}

// GetInput is used to read input from user.
// [goroutine]
func GetInput() {
	l, err := readline.NewEx(
		&readline.Config{
			Prompt: "» ",
			AutoComplete: readline.NewPrefixCompleter(
				readline.PcItem("msh",
					readline.PcItem("start"),
					readline.PcItem("freeze"),
					readline.PcItem("exit"),
				),
				readline.PcItem("mine"),
			),
			FuncFilterInputRune: func(r rune) (rune, bool) {
				switch r {
				case readline.CharCtrlZ: // block CtrlZ feature
					return r, false
				}
				return r, true
			},
		})
	if err != nil {
		fmt.Println("error while starting readline: %s", err.Error())
		return
	}
	defer l.Close()

	log.SetOutput(l.Stderr()) // autorefresh prompt line
	for {
		line, err := l.Readline()
		switch err {
		case nil:
		case io.EOF, readline.ErrInterrupt:
			os.Exit(1)
		default:
			fmt.Println(err.Error())
			continue
		}

		fmt.Println("user input: %s", line)
	}
}

powershell && cmd

first 4 are dark green, last 4 are light green

2022/12/26 19:00:32 color
2022/12/26 19:00:32 color
2022/12/26 19:00:33 color
2022/12/26 19:00:34 color
calling log.SetOutput() inside GetInput() which changes color
2022/12/26 19:00:34 color
2022/12/26 19:00:35 color
2022/12/26 19:00:35 color
2022/12/26 19:00:36 color

git bash

2022/12/26 19:05:44 ←[32mcolor←[0m
2022/12/26 19:05:45 ←[32mcolor←[0m
2022/12/26 19:05:45 ←[32mcolor←[0m
2022/12/26 19:05:46 ←[32mcolor←[0m
calling log.SetOutput() inside GetInput() which changes color
2022/12/26 19:05:46 color
2022/12/26 19:05:47 color
2022/12/26 19:05:47 color
2022/12/26 19:05:48 color

specs

  • windows 10
  • amd64
  • using vscode

question

  • what can I use instead of log.SetOutput(l.Stderr()) to autorefresh the prompt line and having it always at the bottom?
  • is it correct to use log.SetOutput(l.Stdout())?
  • what can I do to avoid the unwanted color change?

@gekigek99 I'm curious if #218 would work for you?

It's a possibility, how can i test it?

(I mean how can I install a specific branch of a library?)

Probably the easiest technique:

  1. Fetch this PR and check it out locally. (If you already have a clone of this repository you can git fetch origin pull/218/head and then git checkout FETCH_HEAD.)
  2. Use go mod replace to repoint at your local checkout: https://thewebivore.com/using-replace-in-go-mod-to-point-to-your-local-module/

edit: fix reference to PR number

#218 indeed solves it!

great job @slingamn! I don't think I ever saw a faster fix ;)

Btw I love your philosophy rep <3