Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ require (
github.com/google/go-cmp v0.7.0
github.com/googleapis/go-spanner-cassandra v0.5.0
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2
github.com/hymkor/go-multiline-ny v0.21.0
github.com/hymkor/go-multiline-ny v0.22.4
github.com/jessevdk/go-flags v1.6.1
github.com/k0kubun/pp/v3 v3.5.0
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/mattn/go-runewidth v0.0.16
github.com/ktr0731/go-fuzzyfinder v0.9.0
github.com/mattn/go-runewidth v0.0.19
github.com/modelcontextprotocol/go-sdk v0.3.0
github.com/ngicks/go-iterator-helper v0.0.21
github.com/nyaosorg/go-readline-ny v1.9.1
github.com/nyaosorg/go-readline-ny v1.14.1
github.com/olekukonko/tablewriter v1.0.9
github.com/samber/lo v1.51.0
github.com/sourcegraph/conc v0.3.0
Expand All @@ -47,7 +48,6 @@ require (
github.com/testcontainers/testcontainers-go/modules/gcloud v0.38.0
github.com/vbauerster/mpb/v8 v8.10.2
go.uber.org/zap v1.27.0
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b
golang.org/x/term v0.36.0
google.golang.org/api v0.256.0
google.golang.org/genai v1.21.0
Expand Down Expand Up @@ -80,6 +80,7 @@ require (
github.com/apstndb/treeprint v0.0.0-20250529153958-e82576b37da6 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clipperhouse/uax29/v2 v2.2.0 // indirect
github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
Expand All @@ -97,6 +98,8 @@ require (
github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/gdamore/encoding v1.0.1 // indirect
github.com/gdamore/tcell/v2 v2.6.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.2 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
Expand All @@ -115,6 +118,8 @@ require (
github.com/itchyny/gojq v0.12.17 // indirect
github.com/itchyny/timefmt-go v0.1.6 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/ktr0731/go-ansisgr v0.1.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/lufia/plan9stats v0.0.0-20250821153705-5981dea3221d // indirect
github.com/magiconair/properties v1.8.10 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
Expand All @@ -130,6 +135,8 @@ require (
github.com/moby/sys/userns v0.1.0 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/nsf/termbox-go v1.1.1 // indirect
github.com/nyaosorg/go-ttyadapter v0.3.0 // indirect
github.com/olekukonko/cat v0.0.0-20250817074551-3280053e4e00 // indirect
github.com/olekukonko/errors v1.1.0 // indirect
github.com/olekukonko/ll v0.1.0 // indirect
Expand Down Expand Up @@ -166,6 +173,7 @@ require (
go.opentelemetry.io/otel/trace v1.38.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.43.0 // indirect
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect
golang.org/x/mod v0.28.0 // indirect
golang.org/x/net v0.46.0 // indirect
golang.org/x/oauth2 v0.33.0 // indirect
Expand Down
34 changes: 28 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2524,6 +2524,8 @@ github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86c
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY=
github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
github.com/cloudspannerecosystem/memefish v0.6.2 h1:0R6C8KdJLLbL3aYk/rzWrwvE+bPRMqj/2MNlNvAzIPo=
github.com/cloudspannerecosystem/memefish v0.6.2/go.mod h1:mVw0xBxy0yOgm990BuR0+nqP8J+yBAAf7N/2uL69rBU=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
Expand Down Expand Up @@ -2629,6 +2631,11 @@ github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw=
github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo=
github.com/gdamore/tcell/v2 v2.6.0 h1:OKbluoP9VYmJwZwq/iLb4BxwKcwGthaa1YNBJIyCySg=
github.com/gdamore/tcell/v2 v2.6.0/go.mod h1:be9omFATkdr0D9qewWW3d+MEvl5dha+Etb5y65J2H8Y=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
Expand Down Expand Up @@ -2749,6 +2756,8 @@ github.com/google/go-pkcs11 v0.2.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMc
github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY=
github.com/google/go-pkcs11 v0.3.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/jsonschema-go v0.2.0 h1:Uh19091iHC56//WOsAd1oRg6yy1P9BpSvpjOL6RcjLQ=
github.com/google/jsonschema-go v0.2.0/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
Expand Down Expand Up @@ -2853,8 +2862,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hymkor/go-multiline-ny v0.21.0 h1:dGxPlvL2dcJvT4jOSCfaeVvcSptbf5q+Z5F92Uc8l8g=
github.com/hymkor/go-multiline-ny v0.21.0/go.mod h1:zrkZWF1DAUsILQ1P8+MSrHOkOnndHl2mC6xki8xRrr8=
github.com/hymkor/go-multiline-ny v0.22.4 h1:Ag2rkBpDnr3jp+AHe1CuXSOQ4AQ8D0+gBNVf+BAX+/0=
github.com/hymkor/go-multiline-ny v0.22.4/go.mod h1:v2lqQooHVAO53WICAIbgTn74bQtzsg4tFn29d+7JPwY=
github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc=
github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
Expand Down Expand Up @@ -2898,7 +2907,13 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/ktr0731/go-ansisgr v0.1.0 h1:fbuupput8739hQbEmZn1cEKjqQFwtCCZNznnF6ANo5w=
github.com/ktr0731/go-ansisgr v0.1.0/go.mod h1:G9lxwgBwH0iey0Dw5YQd7n6PmQTwTuTM/X5Sgm/UrzE=
github.com/ktr0731/go-fuzzyfinder v0.9.0 h1:JV8S118RABzRl3Lh/RsPhXReJWc2q0rbuipzXQH7L4c=
github.com/ktr0731/go-fuzzyfinder v0.9.0/go.mod h1:uybx+5PZFCgMCSDHJDQ9M3nNKx/vccPmGffsXPn2ad8=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
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/lufia/plan9stats v0.0.0-20250821153705-5981dea3221d h1:vFzYZc8yji+9DmNRhpEbs8VBK4CgV/DPfGzeVJSSp/8=
github.com/lufia/plan9stats v0.0.0-20250821153705-5981dea3221d/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=
Expand All @@ -2920,8 +2935,10 @@ github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
Expand Down Expand Up @@ -2959,8 +2976,12 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/ngicks/go-iterator-helper v0.0.21 h1:34dorbGaeL7RgxdymHBqZeL+VLL3hUyAL9QdE5HZrRQ=
github.com/ngicks/go-iterator-helper v0.0.21/go.mod h1:g++KxWVGEkOnIhXVvpNNOdn7ON57aOpfu80ccBvPVHI=
github.com/nyaosorg/go-readline-ny v1.9.1 h1:TpQyXaNWtCN0TCRgUbGLMN8rKoPiwh2Xq58UZkivHmk=
github.com/nyaosorg/go-readline-ny v1.9.1/go.mod h1:54AzdC//M5EzTWRdvUHv2ChuYgp58mRrStTlpxiCmT0=
github.com/nsf/termbox-go v1.1.1 h1:nksUPLCb73Q++DwbYUBEglYBRPZyoXJdrj5L+TkjyZY=
github.com/nsf/termbox-go v1.1.1/go.mod h1:T0cTdVuOwf7pHQNtfhnEbzHbcNyCEcVU4YPpouCbVxo=
github.com/nyaosorg/go-readline-ny v1.14.1 h1:bWyXpR6jRaCXysx4bnioxk36+YjQ6dypHKMjHnzIXdk=
github.com/nyaosorg/go-readline-ny v1.14.1/go.mod h1:/BDf3/H/AScnvey4LoDws1bjTZDB76EE7uKnW2apoKU=
github.com/nyaosorg/go-ttyadapter v0.3.0 h1:/Y7+rGJ0LEcs+AExevwNmND2VJvvpBmgbMuCbntKq3c=
github.com/nyaosorg/go-ttyadapter v0.3.0/go.mod h1:w6ySb/Y8rpr0uIju4vN/TMRHC/6ayabORHmEVs6d/qE=
github.com/olekukonko/cat v0.0.0-20250817074551-3280053e4e00 h1:ZCnkxe9GgWqqBxAk3cIKlQJuaqgOUF/nUtQs8flVTHM=
github.com/olekukonko/cat v0.0.0-20250817074551-3280053e4e00/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0=
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
Expand Down Expand Up @@ -3003,6 +3024,7 @@ github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOA
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
Expand Down
13 changes: 13 additions & 0 deletions internal/mycli/cli_readline.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,19 @@ func initializeMultilineEditor(c *Cli) (*multiline.Editor, History, error) {
return nil, nil, err
}

if c.SystemVariables.EnableFuzzyFinder {
if keyCode, ok := keys.NameToCode[keys.NormalizeName(c.SystemVariables.FuzzyFinderKey)]; ok {
fuzzyCmd := &fuzzyFinderCommand{cli: c}
err = ed.BindKey(keyCode, fuzzyCmd)
if err != nil {
return nil, nil, err
}
} else {
slog.Warn("unknown key name for CLI_FUZZY_FINDER_KEY, fuzzy finder disabled",
"key", c.SystemVariables.FuzzyFinderKey)
}
}

history, err := setupHistory(ed, c.SystemVariables.HistoryFile)
if err != nil {
return nil, nil, err
Expand Down
165 changes: 165 additions & 0 deletions internal/mycli/fuzzy_finder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Copyright 2026 apstndb
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mycli

import (
"context"
"log/slog"
"regexp"

"cloud.google.com/go/spanner/admin/database/apiv1/databasepb"
"github.com/hymkor/go-multiline-ny"
"github.com/ktr0731/go-fuzzyfinder"
"github.com/nyaosorg/go-readline-ny"
)

// fuzzyFinderCommand implements readline.Command for the fuzzy finder feature.
// It detects the current input context and launches a fuzzy finder with
// appropriate candidates. The selected value replaces the current argument
// (completion-style behavior).
type fuzzyFinderCommand struct {
editor *multiline.Editor
cli *Cli
}

func (f *fuzzyFinderCommand) String() string {
return "FUZZY_FINDER"
}

// SetEditor is called by go-multiline-ny's BindKey to inject the editor reference.
func (f *fuzzyFinderCommand) SetEditor(e *multiline.Editor) {
f.editor = e
}

func (f *fuzzyFinderCommand) Call(ctx context.Context, B *readline.Buffer) readline.Result {
// Use current line buffer, not the full multiline text.
// B is the buffer for the current line only, so argStartPos must be relative to it.
input := B.String()
result := detectFuzzyContext(input)
if result.contextType == "" {
return readline.CONTINUE
}

candidates, err := f.fetchCandidates(ctx, result.contextType)
if err != nil {
slog.Debug("fuzzy finder: failed to fetch candidates", "context", result.contextType, "err", err)
return readline.CONTINUE
}
if len(candidates) == 0 {
return readline.CONTINUE
}

// Terminal handoff: move cursor below editor, run fzf, then restore
rewind := f.editor.GotoEndLine()

opts := []fuzzyfinder.Option{}
if result.argPrefix != "" {
opts = append(opts, fuzzyfinder.WithQuery(result.argPrefix))
}

idx, err := fuzzyfinder.Find(candidates, func(i int) string {
return candidates[i]
}, opts...)

rewind()
B.RepaintLastLine()

if err != nil {
// User cancelled (Escape/Ctrl+C) or other error
return readline.CONTINUE
}

selected := candidates[idx]

// Replace the argument portion: delete from argStartPos to end of buffer,
// then insert the selected value.
bufLen := len(B.Buffer)
if result.argStartPos < bufLen {
B.Delete(result.argStartPos, bufLen-result.argStartPos)
}
B.Cursor = result.argStartPos
B.InsertAndRepaint(selected)

return readline.CONTINUE
}

// fuzzyContextType represents what kind of candidates to provide.
type fuzzyContextType = string

const (
fuzzyContextDatabase fuzzyContextType = "database"
)

// fuzzyContextResult holds the detected context, the argument prefix typed so far,
// and the buffer position where the argument starts.
type fuzzyContextResult struct {
contextType fuzzyContextType
argPrefix string // partial argument already typed (used as initial fzf query)
argStartPos int // position in the current line buffer where the argument starts (in runes)
}

// useContextRe matches "USE" followed by optional whitespace and captures any partial argument.
var useContextRe = regexp.MustCompile(`(?i)^\s*USE(\s+(\S*))?$`)

// detectFuzzyContext analyzes the current editor buffer to determine
// what kind of fuzzy completion is appropriate.
func detectFuzzyContext(input string) fuzzyContextResult {
if m := useContextRe.FindStringSubmatch(input); m != nil {
argPrefix := m[2] // may be empty
// argStartPos: position after "USE " in runes.
// Find where the argument starts by locating USE + whitespace.
argStart := len([]rune(input)) - len([]rune(argPrefix))
return fuzzyContextResult{
contextType: fuzzyContextDatabase,
argPrefix: argPrefix,
argStartPos: argStart,
}
}
return fuzzyContextResult{}
}

// fetchCandidates returns completion candidates for the given context type.
func (f *fuzzyFinderCommand) fetchCandidates(ctx context.Context, ctxType fuzzyContextType) ([]string, error) {
switch ctxType {
case fuzzyContextDatabase:
return f.fetchDatabaseCandidates(ctx)
default:
return nil, nil
}
}

// fetchDatabaseCandidates lists databases from the current instance.
func (f *fuzzyFinderCommand) fetchDatabaseCandidates(ctx context.Context) ([]string, error) {
session := f.cli.SessionHandler.GetSession()
if session == nil || session.adminClient == nil {
return nil, nil
}

dbIter := session.adminClient.ListDatabases(ctx, &databasepb.ListDatabasesRequest{
Parent: session.InstancePath(),
})

var databases []string
for db, err := range dbIter.All() {
if err != nil {
return nil, err
}
matched := extractDatabaseRe.FindStringSubmatch(db.GetName())
if len(matched) > 1 {
databases = append(databases, matched[1])
}
}
return databases, nil
}
Loading