这是indexloc提供的服务,不要输入任何密码
Skip to content

nyaosorg/go-readline-ny

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go Reference Go Report Card Wiki License Go Test Awesome

The New Yet another Readline for Go (go-readline-ny)

go-readline-ny is a one-line input library for CUI applications written in Go. It is designed to be extensible to meet diverse needs and has been used in the command-line shell NYAGOS for a long time.

  • Emacs-like key-bindings
  • Input history
  • Word completion (file names, command names, or any names in given array)
  • Syntax highlighting
  • Supported platforms: Windows and Linux
  • Full Unicode (UTF8) support, including:
    • Surrogate-pair
    • Emojis (via clipboard)
    • Zero-width joiner (via clipboard)
    • Variation selectors (via clipboard pasted with Ctrl-Y)
  • Add-Ons:

Zero-Width-Joiner sample on Windows-Terminal

examples

package main

import (
    "context"
    "fmt"

    "github.com/nyaosorg/go-readline-ny"
)

func main() {
    var editor readline.Editor
    text, err := editor.ReadLine(context.Background())
    if err != nil {
        fmt.Printf("ERR=%s\n", err.Error())
    } else {
        fmt.Printf("TEXT=%s\n", text)
    }
}

If the target platform includes Windows, you have to import and use go-colorable like example2.go .

This is a sample demonstrating prompt change, syntax highlighting, filename completion, history browsing, and access to the operating system clipboard.

package main

import (
    "context"
    "fmt"
    "io"
    "os"
    "os/exec"
    "regexp"
    "strings"

    "github.com/atotto/clipboard"
    "github.com/mattn/go-colorable"

    "github.com/nyaosorg/go-readline-ny"
    "github.com/nyaosorg/go-readline-ny/completion"
    "github.com/nyaosorg/go-readline-ny/keys"
    "github.com/nyaosorg/go-readline-ny/simplehistory"
)

type OSClipboard struct{}

func (OSClipboard) Read() (string, error) {
    return clipboard.ReadAll()
}

func (OSClipboard) Write(s string) error {
    return clipboard.WriteAll(s)
}

func main() {
    history := simplehistory.New()

    editor := &readline.Editor{
        PromptWriter: func(w io.Writer) (int, error) {
            return io.WriteString(w, "\x1B[36;22m$ ") // print `$ ` with cyan
        },
        Writer:  colorable.NewColorableStdout(),
        History: history,
        Highlight: []readline.Highlight{
            {Pattern: regexp.MustCompile("&"), Sequence: "\x1B[33;49;22m"},
            {Pattern: regexp.MustCompile(`"[^"]*"`), Sequence: "\x1B[35;49;22m"},
            {Pattern: regexp.MustCompile(`%[^%]*%`), Sequence: "\x1B[36;49;1m"},
            {Pattern: regexp.MustCompile("\u3000"), Sequence: "\x1B[37;41;22m"},
        },
        HistoryCycling: true,
        PredictColor:   [...]string{"\x1B[3;22;34m", "\x1B[23;39m"},
        ResetColor:     "\x1B[0m",
        DefaultColor:   "\x1B[33;49;1m",

        Clipboard: OSClipboard{},
    }

    editor.BindKey(keys.CtrlI, &completion.CmdCompletionOrList2{
        // Characters listed here are excluded from completion.
        Delimiter: "&|><;",
        // Enclose candidates with these characters when they contain spaces
        Enclosure: `"'`,
        // String to append when only one candidate remains
        Postfix: " ",
        // Function for listing candidates
        Candidates: completion.PathComplete,
    })
    // If you do not want to list files with double-tab-key,
    // use `CmdCompletion2` instead of `CmdCompletionOrList2`

    fmt.Println("Tiny Shell. Type Ctrl-D to quit.")
    for {
        text, err := editor.ReadLine(context.Background())

        if err != nil {
            fmt.Printf("ERR=%s\n", err.Error())
            return
        }

        fields := strings.Fields(text)
        if len(fields) <= 0 {
            continue
        }
        cmd := exec.Command(fields[0], fields[1:]...)
        cmd.Stdout = os.Stdout
        cmd.Stderr = os.Stderr
        cmd.Stdin = os.Stdin

        cmd.Run()

        history.Add(text)
    }
}
package main

import (
    "context"
    "fmt"
    "io"
    "os"

    "github.com/nyaosorg/go-readline-ny"
    "github.com/nyaosorg/go-readline-ny/completion"
    "github.com/nyaosorg/go-readline-ny/keys"
)

func mains() error {
    var editor readline.Editor

    editor.PromptWriter = func(w io.Writer) (int, error) {
        return io.WriteString(w, "menu> ")
    }
    candidates := []string{"list", "say", "pewpew", "help", "exit", "Space Command"}

    // If you do not want to list files with double-tab-key,
    // use `CmdCompletion2` instead of `CmdCompletionOrList2`

    editor.BindKey(keys.CtrlI, &completion.CmdCompletionOrList2{
        // Characters listed here are excluded from completion.
        Delimiter: "&|><;",
        // Enclose candidates with these characters when they contain spaces
        Enclosure: `"'`,
        // String to append when only one candidate remains
        Postfix: " ",
        // Function for listing candidates
        Candidates: func(field []string) (forComp []string, forList []string) {
            if len(field) <= 1 {
                return candidates, candidates
            }
            return nil, nil
        },
    })
    ctx := context.Background()
    for {
        line, err := editor.ReadLine(ctx)
        if err != nil {
            return err
        }
        fmt.Printf("TEXT=%#v\n", line)
    }
    return nil
}

func main() {
    if err := mains(); err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
}

Release notes

License

MIT License

Acknowledgements

Author

Contributors 3

  •  
  •  
  •  

Languages