peco/peco로 시작하는 코드로 읽기

14822 단어 Go

개시하다


peco의 원본 코드 읽기에 약간의 진전이 생겼는데, 나는 이 점에 대해 쓰고 싶다.
어떻게 진행됐는지 페코 포장에는 버퍼 리더와 같은 구조체가 들어있지만 이 구조체를 사용하지 않고 표준 입력을 내부 상태로 저장해 봤다.그리고 페코와 같은 동작이 되기 위해 노력했어요.
결과는 기대되지 않지만 대체로 같은 움직임이다.

이루어지다


어제jessevdk/go-flags 사용에 이어서 샘플로 조금 실현되었습니다.
소스 코드의 대부분은 peco.go의 소스 코드입니다.
몇 가지 변경된 점이 있다.
우선 옵션 기능이 없습니다.만약main 함수를 본다면, 나는 당신이 동의할 것이라고 생각합니다.
다음은 파일 작업이 없습니다.대상은 표준 입력일 뿐입니다.그리고 원래의 잘못된 처리가 거의 파괴될 가능성이 높다.
그리고 제가 코드를 추가한 부분은 평어에서'여기로','여기로'의 곳과peco/ctx로 바뀌었습니다.goo.peco/ctx.goo에 AppendLine 함수를 추가했습니다.
sample.go
package main

import (
    "bufio"
    "fmt"
    "os"
    "runtime"

    "github.com/jessevdk/go-flags"
    "github.com/nsf/termbox-go"
    "github.com/peco/peco"
)

type cmdOptions struct {
    OptHelp           bool   `short:"h" long:"help"`
    OptTTY            string `long:"tty"`
    OptQuery          string `long:"query"`
    OptRcfile         string `long:"rcfile"`
    OptNoIgnoreCase   bool   `long:"no-ignore-case"`
    OptVersion        bool   `long:"version"`
    OptBufferSize     int    `long:"buffer-size" short:"b"`
    OptEnableNullSep  bool   `long:"null"`
    OptInitialIndex   int    `long:"initial-index"`
    OptInitialMatcher string `long:"initial-matcher"`
    OptPrompt         string `long:"prompt"`
}

// BufferSize returns the specified buffer size. Fulfills peco.CtxOptions
func (o cmdOptions) BufferSize() int {
    return o.OptBufferSize
}

// EnableNullSep returns tru if --null was specified. Fulfills peco.CtxOptions
func (o cmdOptions) EnableNullSep() bool {
    return o.OptEnableNullSep
}

func (o cmdOptions) InitialIndex() int {
    if o.OptInitialIndex >= 0 {
        return o.OptInitialIndex + 1
    }
    return 1
}

func main() {
    opts := &cmdOptions{}
    p := flags.NewParser(opts, flags.PrintErrors)
    p.Parse()

    ctx := peco.NewCtx(opts)
    defer func() {
        if err := recover(); err != nil {
            fmt.Fprintf(os.Stderr, "Error:\n%s", err)
        }

        if result := ctx.Result(); result != nil {
            for _, match := range result {
                line := match.Output()
                if line[len(line)-1] != '\n' {
                    line = line + "\n"
                }
                fmt.Fprint(os.Stdout, line)
            }
        }
    }()

    // ここから
    in := os.Stdin
    scanner := bufio.NewScanner(in)
    for scanner.Scan() {
        // fmt.Println(scanner.Text())
        // ctx.lines = append(ctx.lines, NewNoMatch(scanner.Text(), ctx.enableSep))
        ctx.AppendLine(scanner.Text())
    }
    // ここまで

    var err error
    err = peco.TtyReady()
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        return
    }
    defer peco.TtyTerm()

    err = termbox.Init()
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        return
    }
    defer termbox.Close()

    // Windows handle Esc/Alt self
    if runtime.GOOS == "windows" {
        termbox.SetInputMode(termbox.InputEsc | termbox.InputAlt)
    }

    view := ctx.NewView()
    filter := ctx.NewFilter()
    input := ctx.NewInput()
    sig := ctx.NewSignalHandler()

    loopers := []interface {
        Loop()
    }{
        view,
        filter,
        input,
        sig,
    }
    for _, looper := range loopers {
        ctx.AddWaitGroup(1)
        go looper.Loop()
    }

    ctx.WaitDone()
}
peco/ctx.go
func (c *Ctx) AppendLine(line string) {
    c.lines = append(c.lines, NewNoMatch(line, c.enableSep))
}
안 된다고 생각하면서peco/ctx를 생각하고 있습니다."go"에 함수를 추가했습니다.함수를 추가하고 명령줄을 실행합니다.
$ go get github.com/peco/peco
$ go build sample.go
$ ls | ./sample
깜깜한 화면으로 변했다.역시 안 된다고 생각하면서 타자를 치는데 화면이 페코랑 똑같아요!!

총결산


커널 해커·오사키의'코드 리더 기술'를 읽은 후 눈이 어지럽기 시작했다.

이 기사를 읽고 나니 열등감이 조금 사라졌다.
기사 내용과 조금 다를 수도 있지만 이번 느낌으로 코드 낭독을 계속하고 싶습니다.

좋은 웹페이지 즐겨찾기