<commit_before>package main

import (
	"bufio"
	"fmt"
	"github.com/codegangsta/cli"
	kval "github.com/kval-access-language/kval-boltdb"
	"github.com/olekukonko/tablewriter"
	"log"
	"os"
	"strings"
)

var instructionLine = "> Enter bucket to explore (CTRL-Q to quit, CTRL-B to go back, ENTER to reset):\n\n"

func main() {
	var file string

	cli.AppHelpTemplate = `NAME:
  {{.Name}} - {{.Usage}}

VERSION:
  {{.Version}}

USAGE:
  {{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}

GLOBAL OPTIONS:
  {{range .VisibleFlags}}{{.}}
  {{end}}
AUTHOR:
  {{range .Authors}}{{ . }}{{end}}
`
	app := cli.NewApp()
	app.Name = "kval-bolter"
	app.Usage = "view boltdb file interactively in your terminal"
	app.Version = "2.0.0-kval"
	app.Author = "Originally by Hasit Mistry. Interactive mode: Ross Spencer"
	//app.Email = ""
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:        "file, f",
			Usage:       "boltdb `FILE` to view",
			Destination: &file,
		},
	}
	app.Action = func(c *cli.Context) error {
		if file == "" {
			cli.ShowAppHelp(c)
			return nil
		}

		var i impl
		i = impl{fmt: &tableFormatter{}}
		if _, err := os.Stat(file); os.IsNotExist(err) {
			log.Fatal(err)
			return err
		}
		i.initDB(file)
		defer kval.Disconnect(i.kb)

		i.readInput()

		return nil
	}
	app.Run(os.Args)
}

func (i *impl) readInput() {
	i.listBuckets()
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		bucket := scanner.Text()
		fmt.Fprintln(os.Stdout, "")
		switch bucket {
		case "\x11":
			return
		case "\x02":
			// TODO: Change KVAL to get first record...
			if !strings.Contains(i.loc, "") || !strings.Contains(i.loc, ">>") {
				fmt.Println("> Going back...")
				i.loc = ""
				i.listBuckets()
			} else {
				i.listBucketItems(bucket, true)
			}
		case "":
			i.listBuckets()
		default:
			i.listBucketItems(bucket, false)
		}
		bucket = ""
	}
}

type formatter interface {
	DumpBuckets([]bucket)
	DumpBucketItems(string, []item)
}

type impl struct {
	kb     kval.Kvalboltdb
	fmt    formatter
	bucket string
	loc    string // where we are in the structure
	cur    string
	root   bool // are we on root
}

type item struct {
	Key   string
	Value string
}

type bucket struct {
	Name string
}

func (i *impl) initDB(file string) {
	var err error
	// Connect to KVAL
	i.kb, err = kval.Connect(file)
	if err != nil {
		log.Fatal(err)
	}
}

func (i *impl) updateLoc(bucket string, goBack bool) string {

	// we've probably an invalid value and want to display
	// ourselves again...
	if bucket == i.cur {
		i.loc = bucket
		return i.loc
	}

	// handle goback
	if goBack {
		s := strings.Split(i.loc, ">>")
		i.loc = strings.Join(s[:len(s)-1], ">>")
		i.bucket = strings.Trim(s[len(s)-2], " ")
		return i.loc
	}

	// handle location on merit...
	if i.loc == "" {
		i.loc = bucket
		i.bucket = bucket
	} else {
		i.loc = i.loc + " >> " + bucket
		i.bucket = bucket
	}
	return i.loc
}

func (i *impl) listBucketItems(bucket string, goBack bool) {
	items := []item{}
	getItems := i.updateLoc(bucket, goBack)
	fmt.Fprintf(os.Stderr, "Query: "+getItems+"\n\n")
	if getItems != "" {
		res, err := kval.Query(i.kb, "GET "+getItems)
		if err != nil {
			if err.Error() != "Cannot GOTO bucket, bucket not found" {
				log.Fatal(err)
			} else {
				fmt.Fprintf(os.Stderr, "> Bucket not found\n")
				if i.root == true {
					i.listBuckets()
					return
				}
				i.listBucketItems(i.loc, true)
			}
		}
		if len(res.Result) == 0 {
			fmt.Fprintf(os.Stderr, "Invalid request.\n\n")
			i.listBucketItems(i.cur, false)
			return
		}

		for k, v := range res.Result {
			if v == kval.Nestedbucket {
				k = k + "*"
				v = ""
			}
			items = append(items, item{Key: string(k), Value: string(v)})
		}
		i.fmt.DumpBucketItems(i.bucket, items)
		i.root = false
		i.cur = getItems
		fmt.Fprint(os.Stdout, instructionLine)
	}
}

func (i *impl) listBuckets() {
	i.root = true
	i.loc = ""

	buckets := []bucket{}

	res, err := kval.Query(i.kb, "GET _")
	if err != nil {
		log.Fatal(err)
	}
	for k, _ := range res.Result {
		buckets = append(buckets, bucket{Name: string(k) + "*"})
	}

	fmt.Fprint(os.Stdout, "DB Layout:\n\n")
	i.fmt.DumpBuckets(buckets)
	fmt.Fprint(os.Stdout, instructionLine)
}

type tableFormatter struct{}

func (tf tableFormatter) DumpBuckets(buckets []bucket) {
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Buckets"})
	for _, b := range buckets {
		row := []string{b.Name}
		table.Append(row)
	}
	table.Render()
	fmt.Println()
}

func (tf tableFormatter) DumpBucketItems(bucket string, items []item) {
	fmt.Printf("Bucket: %s\n", bucket)
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Key", "Value"})
	for _, item := range items {
		row := []string{item.Key, item.Value}
		table.Append(row)
	}
	table.Render()
	fmt.Println()
}
<commit_msg>[documentation] Fulfiling duties under MIT license.<commit_after>package main

import (
	"bufio"
	"fmt"
	"github.com/codegangsta/cli"
	kval "github.com/kval-access-language/kval-boltdb"
	"github.com/olekukonko/tablewriter"
	"log"
	"os"
	"strings"
)

var instructionLine = "> Enter bucket to explore (CTRL-Q to quit, CTRL-B to go back, ENTER to reset):\n\n"

func main() {
	var file string

	cli.AppHelpTemplate = `NAME:
  {{.Name}} - {{.Usage}}

VERSION:
  {{.Version}}

USAGE:
  {{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}

GLOBAL OPTIONS:
  {{range .VisibleFlags}}{{.}}
  {{end}}
AUTHOR:
  {{range .Authors}}{{ . }}{{end}}
COPYRIGHT:
  {{.Copyright}}
`
	app := cli.NewApp()
	app.Name = "bolter"
	app.Usage = "view boltdb file interactively in your terminal"
	app.Version = "2.0.0-kval-fork"
	app.Author = "Originally by Hasit Mistry. Interactive mode: Ross Spencer"
	app.Copyright = "(c) 2016 Hasit Mistry"
	//app.Email = ""
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:        "file, f",
			Usage:       "boltdb `FILE` to view",
			Destination: &file,
		},
	}
	app.Action = func(c *cli.Context) error {
		if file == "" {
			cli.ShowAppHelp(c)
			return nil
		}

		var i impl
		i = impl{fmt: &tableFormatter{}}
		if _, err := os.Stat(file); os.IsNotExist(err) {
			log.Fatal(err)
			return err
		}
		i.initDB(file)
		defer kval.Disconnect(i.kb)

		i.readInput()

		return nil
	}
	app.Run(os.Args)
}

func (i *impl) readInput() {
	i.listBuckets()
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		bucket := scanner.Text()
		fmt.Fprintln(os.Stdout, "")
		switch bucket {
		case "\x11":
			return
		case "\x02":
			// TODO: Change KVAL to get first record...
			if !strings.Contains(i.loc, "") || !strings.Contains(i.loc, ">>") {
				fmt.Println("> Going back...")
				i.loc = ""
				i.listBuckets()
			} else {
				i.listBucketItems(bucket, true)
			}
		case "":
			i.listBuckets()
		default:
			i.listBucketItems(bucket, false)
		}
		bucket = ""
	}
}

type formatter interface {
	DumpBuckets([]bucket)
	DumpBucketItems(string, []item)
}

type impl struct {
	kb     kval.Kvalboltdb
	fmt    formatter
	bucket string
	loc    string // where we are in the structure
	cur    string
	root   bool // are we on root
}

type item struct {
	Key   string
	Value string
}

type bucket struct {
	Name string
}

func (i *impl) initDB(file string) {
	var err error
	// Connect to KVAL
	i.kb, err = kval.Connect(file)
	if err != nil {
		log.Fatal(err)
	}
}

func (i *impl) updateLoc(bucket string, goBack bool) string {

	// we've probably an invalid value and want to display
	// ourselves again...
	if bucket == i.cur {
		i.loc = bucket
		return i.loc
	}

	// handle goback
	if goBack {
		s := strings.Split(i.loc, ">>")
		i.loc = strings.Join(s[:len(s)-1], ">>")
		i.bucket = strings.Trim(s[len(s)-2], " ")
		return i.loc
	}

	// handle location on merit...
	if i.loc == "" {
		i.loc = bucket
		i.bucket = bucket
	} else {
		i.loc = i.loc + " >> " + bucket
		i.bucket = bucket
	}
	return i.loc
}

func (i *impl) listBucketItems(bucket string, goBack bool) {
	items := []item{}
	getItems := i.updateLoc(bucket, goBack)
	fmt.Fprintf(os.Stderr, "Query: "+getItems+"\n\n")
	if getItems != "" {
		res, err := kval.Query(i.kb, "GET "+getItems)
		if err != nil {
			if err.Error() != "Cannot GOTO bucket, bucket not found" {
				log.Fatal(err)
			} else {
				fmt.Fprintf(os.Stderr, "> Bucket not found\n")
				if i.root == true {
					i.listBuckets()
					return
				}
				i.listBucketItems(i.loc, true)
			}
		}
		if len(res.Result) == 0 {
			fmt.Fprintf(os.Stderr, "Invalid request.\n\n")
			i.listBucketItems(i.cur, false)
			return
		}

		for k, v := range res.Result {
			if v == kval.Nestedbucket {
				k = k + "*"
				v = ""
			}
			items = append(items, item{Key: string(k), Value: string(v)})
		}
		i.fmt.DumpBucketItems(i.bucket, items)
		i.root = false
		i.cur = getItems
		fmt.Fprint(os.Stdout, instructionLine)
	}
}

func (i *impl) listBuckets() {
	i.root = true
	i.loc = ""

	buckets := []bucket{}

	res, err := kval.Query(i.kb, "GET _")
	if err != nil {
		log.Fatal(err)
	}
	for k, _ := range res.Result {
		buckets = append(buckets, bucket{Name: string(k) + "*"})
	}

	fmt.Fprint(os.Stdout, "DB Layout:\n\n")
	i.fmt.DumpBuckets(buckets)
	fmt.Fprint(os.Stdout, instructionLine)
}

type tableFormatter struct{}

func (tf tableFormatter) DumpBuckets(buckets []bucket) {
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Buckets"})
	for _, b := range buckets {
		row := []string{b.Name}
		table.Append(row)
	}
	table.Render()
	fmt.Println()
}

func (tf tableFormatter) DumpBucketItems(bucket string, items []item) {
	fmt.Printf("Bucket: %s\n", bucket)
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Key", "Value"})
	for _, item := range items {
		row := []string{item.Key, item.Value}
		table.Append(row)
	}
	table.Render()
	fmt.Println()
}
<|endoftext|>


<commit_before>package books

import (
	"database/sql"
	// "github.com/moshee/gas"
	pg "github.com/moshee/pgtypes"
	"strconv"
	"time"
)

type (
	SeriesKind  int
	Demographic int
	Sex         int
	Credit      int
	Relation    int
	Language    int
	Privileges  int
	ReadStatus  int
)

const (
	Comic SeriesKind = iota
	Novel
)

const (
	Shounen Demographic = iota
	Shoujo
	Seinen
	Josei
)

const (
	Male Sex = iota
	Female
	Other
)

const (
	Scenario Credit = iota
	Art
	Illustration
	Music
)

const (
	Related Relation = iota
	Sequel
	Prequel
	Adaptation
)

const (
	Banned Privileges = 1 << iota
	Administrator
	Moderator
	Contributor
)

func (self Privileges) Is(other Privileges) bool {
	return self&other != 0
}

func (self Privileges) Isnt(other Privileges) bool {
	return self&other == 0
}

const (
	Read ReadStatus = iota
	Owned
	Skipped
)

type BookSeries struct {
	Id int
	SeriesKind
	Title       string
	OtherTitles pg.StringArray
	Summary     sql.NullString
	Vintage     int
	DateAdded   time.Time
	LastUpdated time.Time
	Finished    bool
	NSFW        bool
	AvgRating   sql.NullFloat64
	RatingCount int
	Demographic
	Credits []ProductionCredit
	*Magazine
}

func (self *BookSeries) Related() []RelatedSeries {
	return nil
}

type Author struct {
	Id         int
	Name       string
	NativeName string
	Aliases    pg.StringArray
	Picture    bool
	Birthday   time.Time
	Bio        string
	Sex
}

type ProductionCredit struct {
	*BookSeries
	*Author
	Credit
}

type RelatedSeries struct {
	*BookSeries
	Relation Relation
}

type TranslationGroup struct {
	Id               int
	Name             string
	Summary          sql.NullString
	AvgRating        sql.NullFloat64
	AvgProjectRating sql.NullFloat64
	AvgReleaseRate   time.Duration
}

type Chapter struct {
	Id          int
	Volume      sql.NullInt64
	DisplayName string
	SortNum     int
	Title       sql.NullString
}

type Chapters []*Chapter

// create a representation of the list of chapters with ranges, using display
// names as necessary
func (self Chapters) String() string {
	return ""
}

type Release struct {
	Id int
	*BookSeries
	*TranslationGroup
	*TranslationProject
	Language
	ReleaseDate   time.Time
	Notes         sql.NullString
	IsLastRelease bool
	Chapters
}

type TranslationProject struct {
	Id int
	*BookSeries
	*TranslationGroup
	StartDate time.Time
	EndDate   time.Time
}

func (self *TranslationProject) Members() []*User {
	return nil
}

type User struct {
	Id   int
	Name string
	Pass []byte
	Salt []byte
	Privileges
	VoteWeight   int
	Summary      sql.NullString
	RegisterDate time.Time
	LastActive   time.Time
	Avatar       bool
}

func (self *User) AvatarFile() string {
	if self.Avatar {
		return "u" + strconv.Itoa(self.Id) + ".jpg"
	} else {
		return ""
	}
}

type OwnedChapter struct {
	*Chapter
	Status   ReadStatus
	DateRead time.Time
}

type Magazine struct {
	Id    int
	Title string
	*Publisher
	DateAdded time.Time
	Summary   sql.NullString
}

type Publisher struct {
	Id        int
	Name      string
	DateAdded time.Time
	Summary   sql.NullString
}

type LinkKind struct {
	Id   int
	Name string
}

type Link struct {
	LinkKind
	URL string
}

type Tag struct {
	Id   int
	Name string
}

type BookTag struct {
	Id int
	BookSeries
	Tag
	Spoiler bool
	Weight  float32
}

type TagConsensus struct {
	User
	BookTag
	Vote     int
	VoteDate time.Time
}

type Rating struct {
	Id int
	User
	*Review
	Rating   int
	RateDate time.Time
}

type Review struct {
	Id int
	*Rating
	Body string
}
<commit_msg>reordering and enum friendliness<commit_after>package books

import (
	"database/sql"
	// "github.com/moshee/gas"
	pg "github.com/moshee/pgtypes"
	"strconv"
	"time"
)

type (
	SeriesKind  int
	Demographic int
	Sex         int
	Credit      int
	Relation    int
	Language    int
	Privileges  int
	ReadStatus  int
)

const (
	Comic SeriesKind = iota + 1
	Novel
	Webcomic
)

const (
	Shounen Demographic = iota + 1
	Shoujo
	Seinen
	Josei
)

const (
	Male Sex = iota
	Female
	Other
)

const (
	Scenario Credit = iota
	Art
	Illustration
	Music
)

const (
	Related Relation = iota
	Sequel
	Prequel
	Adaptation
)

const (
	Banned Privileges = 1 << iota
	Administrator
	Moderator
	Contributor
)

func (self Privileges) Is(other Privileges) bool {
	return self&other != 0
}

func (self Privileges) Isnt(other Privileges) bool {
	return self&other == 0
}

const (
	Read ReadStatus = iota
	Owned
	Skipped
)

type BookSeries struct {
	Id int
	SeriesKind
	Title       string
	OtherTitles pg.StringArray
	Summary     sql.NullString
	Vintage     int
	DateAdded   time.Time
	LastUpdated time.Time
	Finished    bool
	NSFW        bool
	AvgRating   sql.NullFloat64
	RatingCount int
	Demographic
	Credits []ProductionCredit
	*Magazine
}

func (self *BookSeries) Related() []RelatedSeries {
	return nil
}

type Author struct {
	Id         int
	Name       string
	NativeName string
	Aliases    pg.StringArray
	Picture    bool
	Birthday   time.Time
	Bio        string
	Sex
}

type ProductionCredit struct {
	*BookSeries
	*Author
	Credit
}

type RelatedSeries struct {
	*BookSeries
	Relation Relation
}

type TranslationGroup struct {
	Id               int
	Name             string
	Summary          sql.NullString
	AvgRating        sql.NullFloat64
	AvgProjectRating sql.NullFloat64
	AvgReleaseRate   time.Duration
}

type Chapter struct {
	Id          int
	Volume      sql.NullInt64
	DisplayName string
	SortNum     int
	Title       sql.NullString
}

type Chapters []*Chapter

// create a representation of the list of chapters with ranges, using display
// names as necessary
func (self Chapters) String() string {
	return ""
}

type Release struct {
	Id int
	*BookSeries
	*TranslationGroup
	*TranslationProject
	Language
	ReleaseDate   time.Time
	Notes         sql.NullString
	IsLastRelease bool
	Chapters
}

type TranslationProject struct {
	Id int
	*BookSeries
	*TranslationGroup
	StartDate time.Time
	EndDate   time.Time
}

func (self *TranslationProject) Members() []*User {
	return nil
}

type User struct {
	Id   int
	Name string
	Pass []byte
	Salt []byte
	Privileges
	VoteWeight   int
	Summary      sql.NullString
	RegisterDate time.Time
	LastActive   time.Time
	Avatar       bool
}

func (self *User) AvatarFile() string {
	if self.Avatar {
		return "u" + strconv.Itoa(self.Id) + ".jpg"
	} else {
		return ""
	}
}

type OwnedChapter struct {
	*Chapter
	Status   ReadStatus
	DateRead time.Time
}

type Magazine struct {
	Id    int
	Title string
	*Publisher
	DateAdded time.Time
	Summary   sql.NullString
}

type Publisher struct {
	Id        int
	Name      string
	DateAdded time.Time
	Summary   sql.NullString
}

type LinkKind struct {
	Id   int
	Name string
}

type Link struct {
	LinkKind
	URL string
}

type Tag struct {
	Id   int
	Name string
}

type BookTag struct {
	Id int
	BookSeries
	Tag
	Spoiler bool
	Weight  float32
}

type TagConsensus struct {
	User
	BookTag
	Vote     int
	VoteDate time.Time
}

type Rating struct {
	Id int
	User
	Rating   int
	RateDate time.Time
	*Review
}

type Review struct {
	Id int
	*Rating
	Body string
}
<|endoftext|>


<commit_before>//+build windows

package tui

import (
	"os"
	"syscall"

	"github.com/junegunn/fzf/src/util"
	"golang.org/x/sys/windows"
)

var (
	consoleFlagsInput  = uint32(windows.ENABLE_VIRTUAL_TERMINAL_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_EXTENDED_FLAGS)
	consoleFlagsOutput = uint32(windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING | windows.ENABLE_PROCESSED_OUTPUT | windows.DISABLE_NEWLINE_AUTO_RETURN)
)

// IsLightRendererSupported checks to see if the Light renderer is supported
func IsLightRendererSupported() bool {
	var oldState uint32
	// enable vt100 emulation (https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences)
	if windows.GetConsoleMode(windows.Stderr, &oldState) != nil {
		return false
	}
	// attempt to set mode to determine if we support VT 100 codes. This will work on newer Windows 10
	// version:
	canSetVt100 := windows.SetConsoleMode(windows.Stderr, oldState|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) == nil
	var checkState uint32
	if windows.GetConsoleMode(windows.Stderr, &checkState) != nil ||
		(checkState&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) != windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING {
		return false
	}
	windows.SetConsoleMode(windows.Stderr, oldState)
	return canSetVt100
}

func (r *LightRenderer) defaultTheme() *ColorTheme {
	// the getenv check is borrowed from here: https://github.com/gdamore/tcell/commit/0c473b86d82f68226a142e96cc5a34c5a29b3690#diff-b008fcd5e6934bf31bc3d33bf49f47d8R178:
	if !IsLightRendererSupported() || os.Getenv("ConEmuPID") != "" || os.Getenv("TCELL_TRUECOLOR") == "disable" {
		return Default16
	}
	return Dark256
}

func (r *LightRenderer) initPlatform() error {
	//outHandle := windows.Stdout
	outHandle, _ := syscall.Open("CONOUT$", syscall.O_RDWR, 0)
	// enable vt100 emulation (https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences)
	if err := windows.GetConsoleMode(windows.Handle(outHandle), &r.origStateOutput); err != nil {
		return err
	}
	r.outHandle = uintptr(outHandle)
	inHandle, _ := syscall.Open("CONIN$", syscall.O_RDWR, 0)
	if err := windows.GetConsoleMode(windows.Handle(inHandle), &r.origStateInput); err != nil {
		return err
	}
	r.inHandle = uintptr(inHandle)

	r.setupTerminal()

	// channel for non-blocking reads. Buffer to make sure
	// we get the ESC sets:
	r.ttyinChannel = make(chan byte, 12)

	// the following allows for non-blocking IO.
	// syscall.SetNonblock() is a NOOP under Windows.
	go func() {
		fd := int(r.inHandle)
		b := make([]byte, 1)
		for {
			// HACK: if run from PSReadline, something resets ConsoleMode to remove ENABLE_VIRTUAL_TERMINAL_INPUT.
			_ = windows.SetConsoleMode(windows.Handle(r.inHandle), consoleFlagsInput)

			_, err := util.Read(fd, b)
			if err == nil {
				r.ttyinChannel <- b[0]
			}
		}
	}()

	return nil
}

func (r *LightRenderer) closePlatform() {
	windows.SetConsoleMode(windows.Handle(r.outHandle), r.origStateOutput)
	windows.SetConsoleMode(windows.Handle(r.inHandle), r.origStateInput)
}

func openTtyIn() *os.File {
	// not used
	return nil
}

func (r *LightRenderer) setupTerminal() error {
	if err := windows.SetConsoleMode(windows.Handle(r.outHandle), consoleFlagsOutput); err != nil {
		return err
	}
	return windows.SetConsoleMode(windows.Handle(r.inHandle), consoleFlagsInput)
}

func (r *LightRenderer) restoreTerminal() error {
	if err := windows.SetConsoleMode(windows.Handle(r.inHandle), r.origStateInput); err != nil {
		return err
	}
	return windows.SetConsoleMode(windows.Handle(r.outHandle), r.origStateOutput)
}

func (r *LightRenderer) updateTerminalSize() {
	var bufferInfo windows.ConsoleScreenBufferInfo
	if err := windows.GetConsoleScreenBufferInfo(windows.Handle(r.outHandle), &bufferInfo); err != nil {
		r.width = getEnv("COLUMNS", defaultWidth)
		r.height = r.maxHeightFunc(getEnv("LINES", defaultHeight))

	} else {
		r.width = int(bufferInfo.Window.Right - bufferInfo.Window.Left)
		r.height = r.maxHeightFunc(int(bufferInfo.Window.Bottom - bufferInfo.Window.Top))
	}
}

func (r *LightRenderer) findOffset() (row int, col int) {
	var bufferInfo windows.ConsoleScreenBufferInfo
	if err := windows.GetConsoleScreenBufferInfo(windows.Handle(r.outHandle), &bufferInfo); err != nil {
		return -1, -1
	}
	return int(bufferInfo.CursorPosition.X), int(bufferInfo.CursorPosition.Y)
}

func (r *LightRenderer) getch(nonblock bool) (int, bool) {
	if nonblock {
		select {
		case bc := <-r.ttyinChannel:
			return int(bc), true
		default:
			return 0, false
		}
	} else {
		bc := <-r.ttyinChannel
		return int(bc), true
	}
}
<commit_msg>Ensure proper ESC seq handling under Windows preview mode (#2430)<commit_after>//+build windows

package tui

import (
	"os"
	"syscall"
	"time"

	"github.com/junegunn/fzf/src/util"
	"golang.org/x/sys/windows"
)

const (
	timeoutInterval = 10
)

var (
	consoleFlagsInput  = uint32(windows.ENABLE_VIRTUAL_TERMINAL_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_EXTENDED_FLAGS)
	consoleFlagsOutput = uint32(windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING | windows.ENABLE_PROCESSED_OUTPUT | windows.DISABLE_NEWLINE_AUTO_RETURN)
)

// IsLightRendererSupported checks to see if the Light renderer is supported
func IsLightRendererSupported() bool {
	var oldState uint32
	// enable vt100 emulation (https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences)
	if windows.GetConsoleMode(windows.Stderr, &oldState) != nil {
		return false
	}
	// attempt to set mode to determine if we support VT 100 codes. This will work on newer Windows 10
	// version:
	canSetVt100 := windows.SetConsoleMode(windows.Stderr, oldState|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) == nil
	var checkState uint32
	if windows.GetConsoleMode(windows.Stderr, &checkState) != nil ||
		(checkState&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) != windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING {
		return false
	}
	windows.SetConsoleMode(windows.Stderr, oldState)
	return canSetVt100
}

func (r *LightRenderer) defaultTheme() *ColorTheme {
	// the getenv check is borrowed from here: https://github.com/gdamore/tcell/commit/0c473b86d82f68226a142e96cc5a34c5a29b3690#diff-b008fcd5e6934bf31bc3d33bf49f47d8R178:
	if !IsLightRendererSupported() || os.Getenv("ConEmuPID") != "" || os.Getenv("TCELL_TRUECOLOR") == "disable" {
		return Default16
	}
	return Dark256
}

func (r *LightRenderer) initPlatform() error {
	//outHandle := windows.Stdout
	outHandle, _ := syscall.Open("CONOUT$", syscall.O_RDWR, 0)
	// enable vt100 emulation (https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences)
	if err := windows.GetConsoleMode(windows.Handle(outHandle), &r.origStateOutput); err != nil {
		return err
	}
	r.outHandle = uintptr(outHandle)
	inHandle, _ := syscall.Open("CONIN$", syscall.O_RDWR, 0)
	if err := windows.GetConsoleMode(windows.Handle(inHandle), &r.origStateInput); err != nil {
		return err
	}
	r.inHandle = uintptr(inHandle)

	r.setupTerminal()

	// channel for non-blocking reads. Buffer to make sure
	// we get the ESC sets:
	r.ttyinChannel = make(chan byte, 1024)

	// the following allows for non-blocking IO.
	// syscall.SetNonblock() is a NOOP under Windows.
	go func() {
		fd := int(r.inHandle)
		b := make([]byte, 1)
		for {
			_, err := util.Read(fd, b)
			if err == nil {
				r.ttyinChannel <- b[0]
			}
		}
	}()

	return nil
}

func (r *LightRenderer) closePlatform() {
	windows.SetConsoleMode(windows.Handle(r.outHandle), r.origStateOutput)
	windows.SetConsoleMode(windows.Handle(r.inHandle), r.origStateInput)
}

func openTtyIn() *os.File {
	// not used
	return nil
}

func (r *LightRenderer) setupTerminal() error {
	if err := windows.SetConsoleMode(windows.Handle(r.outHandle), consoleFlagsOutput); err != nil {
		return err
	}
	return windows.SetConsoleMode(windows.Handle(r.inHandle), consoleFlagsInput)
}

func (r *LightRenderer) restoreTerminal() error {
	if err := windows.SetConsoleMode(windows.Handle(r.inHandle), r.origStateInput); err != nil {
		return err
	}
	return windows.SetConsoleMode(windows.Handle(r.outHandle), r.origStateOutput)
}

func (r *LightRenderer) updateTerminalSize() {
	var bufferInfo windows.ConsoleScreenBufferInfo
	if err := windows.GetConsoleScreenBufferInfo(windows.Handle(r.outHandle), &bufferInfo); err != nil {
		r.width = getEnv("COLUMNS", defaultWidth)
		r.height = r.maxHeightFunc(getEnv("LINES", defaultHeight))

	} else {
		r.width = int(bufferInfo.Window.Right - bufferInfo.Window.Left)
		r.height = r.maxHeightFunc(int(bufferInfo.Window.Bottom - bufferInfo.Window.Top))
	}
}

func (r *LightRenderer) findOffset() (row int, col int) {
	var bufferInfo windows.ConsoleScreenBufferInfo
	if err := windows.GetConsoleScreenBufferInfo(windows.Handle(r.outHandle), &bufferInfo); err != nil {
		return -1, -1
	}
	return int(bufferInfo.CursorPosition.X), int(bufferInfo.CursorPosition.Y)
}

func (r *LightRenderer) getch(nonblock bool) (int, bool) {
	if nonblock {
		select {
		case bc := <-r.ttyinChannel:
			return int(bc), true
		case <-time.After(timeoutInterval * time.Millisecond):
			return 0, false
		}
	} else {
		bc := <-r.ttyinChannel
		return int(bc), true
	}
}
<|endoftext|>


<commit_before><commit_msg>Sep/2020 Automated certificate updates<commit_after><|endoftext|>


<commit_before>// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build !js || !wasm

package req

import "net/http"

// RoundTrip implements the RoundTripper interface.
//
// For higher-level HTTP client support (such as handling of cookies
// and redirects), see Get, Post, and the Client type.
//
// Like the RoundTripper interface, the error types returned
// by RoundTrip are unspecified.
func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
	resp, err = t.roundTrip(req)
	if err != nil {
		return
	}
	t.handleResponseBody(resp)
	return
}
<commit_msg>fix v2 build error when go version < 1.17 #84<commit_after>// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package req

import "net/http"

// RoundTrip implements the RoundTripper interface.
//
// For higher-level HTTP client support (such as handling of cookies
// and redirects), see Get, Post, and the Client type.
//
// Like the RoundTripper interface, the error types returned
// by RoundTrip are unspecified.
func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
	resp, err = t.roundTrip(req)
	if err != nil {
		return
	}
	t.handleResponseBody(resp)
	return
}
<|endoftext|>