From 1a7e8694720ee267bf554fbb321c6db7867e29ac Mon Sep 17 00:00:00 2001 From: Hasit Mistry Date: Thu, 20 Oct 2022 08:16:21 -0700 Subject: [PATCH 1/2] Initial setup using charmbracelet/bubbletea --- bolter.go => bolter.go-backup | 7 +-- cmd/root.go | 51 +++++++++++++++++++++ cmd/update.go | 28 ++++++++++++ go.mod | 30 +++++++++---- go.sum | 84 ++++++++++++++++++++++++----------- internal/config/config.go | 1 + internal/tui/keys.go | 30 +++++++++++++ internal/tui/model.go | 40 +++++++++++++++++ main.go | 7 +++ 9 files changed, 238 insertions(+), 40 deletions(-) rename bolter.go => bolter.go-backup (96%) create mode 100644 cmd/root.go create mode 100644 cmd/update.go create mode 100644 internal/config/config.go create mode 100644 internal/tui/keys.go create mode 100644 internal/tui/model.go create mode 100644 main.go diff --git a/bolter.go b/bolter.go-backup similarity index 96% rename from bolter.go rename to bolter.go-backup index 9e9e398..b2645df 100644 --- a/bolter.go +++ b/bolter.go-backup @@ -12,10 +12,6 @@ import ( "github.com/urfave/cli" ) -// Terminal lines... -const instructionLine = "> Enter bucket to explore (CTRL-X to quit, CTRL-B to go back, ENTER to go back to ROOT Bucket):" -const goingBack = "> Going back..." - func main() { var file string @@ -41,7 +37,7 @@ COPYRIGHT: app.Usage = "view boltdb file interactively in your terminal" app.Version = "2.0.1" app.Authors = []cli.Author{ - cli.Author{ + { Name: "Hasit Mistry", Email: "hasitnm@gmail.com", }, @@ -136,7 +132,6 @@ func (i *impl) initDB(file string) { } func (i *impl) updateLoc(bucket string, goBack bool) string { - // we've probably an invalid value and want to display // ourselves again... if bucket == i.cache { diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..291ad5a --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,51 @@ +package cmd + +import ( + "fmt" + "log" + "os" + + tea "github.com/charmbracelet/bubbletea" + "github.com/hasit/bolter/internal/tui" + "github.com/spf13/cobra" +) + +var rootCmd = &cobra.Command{ + Use: "bolter", + Short: "view boltdb file interactively in your terminal", + Version: "0.1.0", + Args: cobra.MaximumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + file, err := cmd.Flags().GetString("file") + if err != nil { + log.Fatal(err) + } + + if file == "" { + log.Fatal("--file cannot be empty") + } + + m := tui.New(file) + var opts []tea.ProgramOption + + // Always append alt screen program option. + opts = append(opts, tea.WithAltScreen()) + + // Initialize and start app. + p := tea.NewProgram(m, opts...) + if err := p.Start(); err != nil { + log.Fatal("Failed to start fm", err) + } + }, +} + +// Execute runs the root command and starts the application. +func Execute() { + rootCmd.AddCommand(updateCmd) + rootCmd.PersistentFlags().String("file", "", "boltdb file to view") + + if err := rootCmd.Execute(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} diff --git a/cmd/update.go b/cmd/update.go new file mode 100644 index 0000000..cbd7e11 --- /dev/null +++ b/cmd/update.go @@ -0,0 +1,28 @@ +package cmd + +import ( + "log" + "os" + "os/exec" + + "github.com/spf13/cobra" +) + +var updateCmd = &cobra.Command{ + Use: "update", + Short: "Update bolter to the latest version", + Long: `Update bolter to the latest version.`, + Run: func(cmd *cobra.Command, args []string) { + updateCommand := exec.Command("bash", "-c", "curl -sfL https://raw.githubusercontent.com/hasit/bolter/main/install.sh | sh") + updateCommand.Stdin = os.Stdin + updateCommand.Stdout = os.Stdout + updateCommand.Stderr = os.Stderr + + err := updateCommand.Run() + if err != nil { + log.Fatal(err) + } + + os.Exit(0) + }, +} diff --git a/go.mod b/go.mod index 39c2794..2467f6b 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,27 @@ module github.com/hasit/bolter -go 1.13 +go 1.19 require ( - github.com/boltdb/bolt v1.3.1 // indirect - github.com/kval-access-language/kval-boltdb v0.0.0-20170330045345-f3797777c95e - github.com/kval-access-language/kval-parse v0.0.0-20170504112528-b96aa5a26330 // indirect - github.com/kval-access-language/kval-scanner v0.0.0-20170504112421-4f097cacd289 // indirect - github.com/olekukonko/tablewriter v0.0.2 - github.com/pkg/errors v0.8.1 // indirect - github.com/urfave/cli v1.22.1 + github.com/charmbracelet/bubbles v0.14.0 + github.com/charmbracelet/bubbletea v0.22.1 + github.com/spf13/cobra v1.6.0 +) + +require ( + github.com/containerd/console v1.0.3 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-localereader v0.0.1 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect + github.com/muesli/cancelreader v0.2.2 // indirect + github.com/muesli/reflow v0.3.0 // indirect + github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect + golang.org/x/text v0.3.7 // indirect ) diff --git a/go.sum b/go.sum index 1d09669..092fa46 100644 --- a/go.sum +++ b/go.sum @@ -1,27 +1,59 @@ -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/kval-access-language/kval-boltdb v0.0.0-20170330045345-f3797777c95e h1:6eQQkLvMgIY9ecZKVtEsKdUeApg6qkNl8IwJp6cZBNg= -github.com/kval-access-language/kval-boltdb v0.0.0-20170330045345-f3797777c95e/go.mod h1:CJfrSSteer+JJgIkdw/LU7Ss1CiZ6G/+oIfo4nJ1P/s= -github.com/kval-access-language/kval-parse v0.0.0-20170504112528-b96aa5a26330 h1:u+bu63lKw/77wcyhzRB9YwipGEa4l3et/hu4xkcX2cQ= -github.com/kval-access-language/kval-parse v0.0.0-20170504112528-b96aa5a26330/go.mod h1:sIViryZLFGwtty1cz01GVfqCzHR2j5O7ZCcuYiGJAJA= -github.com/kval-access-language/kval-scanner v0.0.0-20170504112421-4f097cacd289 h1:xp6dE/eMUsoTqp/A4p846HSDlETgYPcW+gmtSW7G0tc= -github.com/kval-access-language/kval-scanner v0.0.0-20170504112421-4f097cacd289/go.mod h1:YAawD4QhDnNbLB6455T6SheCYnZh90kII4jhq5HWzAQ= -github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2 h1:sq53g+DWf0J6/ceFUHpQ0nAEb6WgM++fq16MZ91cS6o= -github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/charmbracelet/bubbles v0.14.0 h1:DJfCwnARfWjZLvMglhSQzo76UZ2gucuHPy9jLWX45Og= +github.com/charmbracelet/bubbles v0.14.0/go.mod h1:bbeTiXwPww4M031aGi8UK2HT9RDWoiNibae+1yCMtcc= +github.com/charmbracelet/bubbletea v0.21.0/go.mod h1:GgmJMec61d08zXsOhqRC/AiOx4K4pmz+VIcRIm1FKr4= +github.com/charmbracelet/bubbletea v0.22.1 h1:z66q0LWdJNOWEH9zadiAIXp2GN1AWrwNXU8obVY9X24= +github.com/charmbracelet/bubbletea v0.22.1/go.mod h1:8/7hVvbPN6ZZPkczLiB8YpLkLJ0n7DMho5Wvfd2X1C0= +github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= +github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs= +github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= +github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= +github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34= +github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho= +github.com/muesli/cancelreader v0.2.0/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= +github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs= +github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 h1:QANkGiGr39l1EESqrE0gZw0/AJNYzIvoGLhIoVYtluI= +github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= +github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI= +github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..d912156 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1 @@ +package config diff --git a/internal/tui/keys.go b/internal/tui/keys.go new file mode 100644 index 0000000..ceefb00 --- /dev/null +++ b/internal/tui/keys.go @@ -0,0 +1,30 @@ +package tui + +import "github.com/charmbracelet/bubbles/key" + +// KeyMap defines the keybindings for the app. +type KeyMap struct { + Quit key.Binding + Exit key.Binding + ToggleBox key.Binding + OpenFile key.Binding + ReloadConfig key.Binding +} + +// DefaultKeyMap returns a set of default keybindings. +func DefaultKeyMap() KeyMap { + return KeyMap{ + Quit: key.NewBinding( + key.WithKeys("ctrl+c"), + ), + Exit: key.NewBinding( + key.WithKeys("q"), + ), + ToggleBox: key.NewBinding( + key.WithKeys("tab"), + ), + OpenFile: key.NewBinding( + key.WithKeys(" "), + ), + } +} diff --git a/internal/tui/model.go b/internal/tui/model.go new file mode 100644 index 0000000..01ba9bd --- /dev/null +++ b/internal/tui/model.go @@ -0,0 +1,40 @@ +package tui + +import tea "github.com/charmbracelet/bubbletea" + +// type sessionState int + +// const ( +// idleState sessionState = iota +// showCodeState +// showImageState +// showMarkdownState +// showPdfState +// ) + +// Bubble represents the properties of the UI. +type Bubble struct { + // state sessionState + keys KeyMap +} + +func New(file string) Bubble { + return Bubble{ + keys: DefaultKeyMap(), + } +} + +// Init intializes the UI. +func (b Bubble) Init() tea.Cmd { + return nil +} + +// Update handles all UI interactions. +func (b Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + return b, nil +} + +// View returns a string representation of the UI. +func (b Bubble) View() string { + return "" +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..36d77a7 --- /dev/null +++ b/main.go @@ -0,0 +1,7 @@ +package main // import "github.com/hasit/bolter" + +import "github.com/hasit/bolter/cmd" + +func main() { + cmd.Execute() +} From db83ce002f623727c0ef2e5f59b844a443ad65de Mon Sep 17 00:00:00 2001 From: Hasit Mistry Date: Thu, 20 Oct 2022 14:52:30 -0700 Subject: [PATCH 2/2] Add basic key handling --- cmd/root.go | 2 +- {sample-db => example}/test-db.bolt | Bin go.mod | 1 + go.sum | 3 ++ internal/config/config.go | 1 - internal/tui/init.go | 31 +++++++++++++++++ internal/tui/keys.go | 30 ----------------- internal/tui/model.go | 50 ++++++++++------------------ internal/tui/update.go | 26 +++++++++++++++ internal/tui/view.go | 20 +++++++++++ main.go | 2 +- 11 files changed, 100 insertions(+), 66 deletions(-) rename {sample-db => example}/test-db.bolt (100%) delete mode 100644 internal/config/config.go create mode 100644 internal/tui/init.go delete mode 100644 internal/tui/keys.go create mode 100644 internal/tui/update.go create mode 100644 internal/tui/view.go diff --git a/cmd/root.go b/cmd/root.go index 291ad5a..3d1014d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -42,7 +42,7 @@ var rootCmd = &cobra.Command{ // Execute runs the root command and starts the application. func Execute() { rootCmd.AddCommand(updateCmd) - rootCmd.PersistentFlags().String("file", "", "boltdb file to view") + rootCmd.PersistentFlags().StringP("file", "f", "", "boltdb file to view") if err := rootCmd.Execute(); err != nil { fmt.Fprintln(os.Stderr, err) diff --git a/sample-db/test-db.bolt b/example/test-db.bolt similarity index 100% rename from sample-db/test-db.bolt rename to example/test-db.bolt diff --git a/go.mod b/go.mod index 2467f6b..cc0db1e 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/charmbracelet/bubbles v0.14.0 github.com/charmbracelet/bubbletea v0.22.1 github.com/spf13/cobra v1.6.0 + go.etcd.io/bbolt v1.3.6 ) require ( diff --git a/go.sum b/go.sum index 092fa46..231604b 100644 --- a/go.sum +++ b/go.sum @@ -43,6 +43,9 @@ github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI= github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= +go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/internal/config/config.go b/internal/config/config.go deleted file mode 100644 index d912156..0000000 --- a/internal/config/config.go +++ /dev/null @@ -1 +0,0 @@ -package config diff --git a/internal/tui/init.go b/internal/tui/init.go new file mode 100644 index 0000000..3ddcd06 --- /dev/null +++ b/internal/tui/init.go @@ -0,0 +1,31 @@ +package tui + +import ( + tea "github.com/charmbracelet/bubbletea" + "go.etcd.io/bbolt" +) + +// Init intializes the UI. +func (m Model) Init() tea.Cmd { + db, err := bbolt.Open(m.file, 0400, nil) + if err != nil { + return tea.Quit + } + m.db = db + + err = m.db.View(func(tx *bbolt.Tx) error { + return tx.ForEach(func(bucketName []byte, bucketPtr *bbolt.Bucket) error { + b := bucket{ + name: string(bucketName), + bucket: bucketPtr, + } + m.buckets = append(m.buckets, b) + return nil + }) + }) + if err != nil { + return tea.Quit + } + + return nil +} diff --git a/internal/tui/keys.go b/internal/tui/keys.go deleted file mode 100644 index ceefb00..0000000 --- a/internal/tui/keys.go +++ /dev/null @@ -1,30 +0,0 @@ -package tui - -import "github.com/charmbracelet/bubbles/key" - -// KeyMap defines the keybindings for the app. -type KeyMap struct { - Quit key.Binding - Exit key.Binding - ToggleBox key.Binding - OpenFile key.Binding - ReloadConfig key.Binding -} - -// DefaultKeyMap returns a set of default keybindings. -func DefaultKeyMap() KeyMap { - return KeyMap{ - Quit: key.NewBinding( - key.WithKeys("ctrl+c"), - ), - Exit: key.NewBinding( - key.WithKeys("q"), - ), - ToggleBox: key.NewBinding( - key.WithKeys("tab"), - ), - OpenFile: key.NewBinding( - key.WithKeys(" "), - ), - } -} diff --git a/internal/tui/model.go b/internal/tui/model.go index 01ba9bd..5ae4376 100644 --- a/internal/tui/model.go +++ b/internal/tui/model.go @@ -1,40 +1,24 @@ package tui -import tea "github.com/charmbracelet/bubbletea" - -// type sessionState int - -// const ( -// idleState sessionState = iota -// showCodeState -// showImageState -// showMarkdownState -// showPdfState -// ) - -// Bubble represents the properties of the UI. -type Bubble struct { - // state sessionState - keys KeyMap +import "go.etcd.io/bbolt" + +// Model represents the properties of the UI. +type Model struct { + cursor int + file string + db *bbolt.DB + buckets []bucket } -func New(file string) Bubble { - return Bubble{ - keys: DefaultKeyMap(), - } +type bucket struct { + name string + bucket *bbolt.Bucket } -// Init intializes the UI. -func (b Bubble) Init() tea.Cmd { - return nil -} - -// Update handles all UI interactions. -func (b Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - return b, nil -} - -// View returns a string representation of the UI. -func (b Bubble) View() string { - return "" +func New(file string) Model { + return Model{ + file: file, + buckets: make([]bucket, 0), + cursor: 0, + } } diff --git a/internal/tui/update.go b/internal/tui/update.go new file mode 100644 index 0000000..06cfa47 --- /dev/null +++ b/internal/tui/update.go @@ -0,0 +1,26 @@ +package tui + +import ( + tea "github.com/charmbracelet/bubbletea" +) + +// Update handles all UI interactions. +func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.String() { + case "ctrl+c", "q": + return m, tea.Quit + case "up", "k": + if m.cursor > 0 { + m.cursor-- + } + case "down", "j": + if m.cursor < len(m.buckets)-1 { + m.cursor++ + } + case "enter", " ": + } + } + return m, nil +} diff --git a/internal/tui/view.go b/internal/tui/view.go new file mode 100644 index 0000000..a103252 --- /dev/null +++ b/internal/tui/view.go @@ -0,0 +1,20 @@ +package tui + +import "fmt" + +// View returns a string representation of the UI. +func (m Model) View() string { + s := fmt.Sprintf("Viewing boltdb file: %s\n\n", m.file) + + for i, bucket := range m.buckets { + cursor := " " + if m.cursor == i { + cursor = ">" + } + + s += fmt.Sprintf("%s %s", cursor, bucket) + } + + s += "\nPress q to quit.\n" + return s +} diff --git a/main.go b/main.go index 36d77a7..3b1c099 100644 --- a/main.go +++ b/main.go @@ -1,4 +1,4 @@ -package main // import "github.com/hasit/bolter" +package main import "github.com/hasit/bolter/cmd"