Skip to content

Commit

Permalink
Implement main features
Browse files Browse the repository at this point in the history
  • Loading branch information
sandro-h committed May 1, 2021
1 parent 1cd7943 commit 35e3387
Show file tree
Hide file tree
Showing 4 changed files with 212 additions and 34 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
BASE_VERSION=0.0.1
BASE_VERSION=0.0.2
REPO_OWNER=sandro-h
BUILD_CENTOS_IMAGE_VERSION=0.0.1
BUILD_CENTOS_IMAGE_TAG=ghcr.io/${REPO_OWNER}/snippet-centos-build:${BUILD_CENTOS_IMAGE_VERSION}
Expand Down Expand Up @@ -75,7 +75,7 @@ print-version:

.PHONY: build-all-optimized
build-all-optimized: EXTRA_BUILD_ARGS=-ldflags='-s -w'
build-all-optimized: build-linux build-centos # build-windows
build-all-optimized: build-linux build-centos build-windows

upx:
wget https://github.com/upx/upx/releases/download/v3.96/upx-3.96-amd64_linux.tar.xz
Expand All @@ -87,4 +87,4 @@ compress-binaries: upx
chmod +x snippet snippet-centos
upx/upx -q --brute snippet
upx/upx -q --brute snippet-centos
# upx/upx -q --brute snippet.exe
upx/upx -q --brute snippet.exe
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ module github.com/sandro-h/snippet
go 1.16

require (
fyne.io/fyne v1.4.3
fyne.io/fyne/v2 v2.0.3 // indirect
fyne.io/fyne/v2 v2.0.3
github.com/go-vgo/robotgo v0.93.1
github.com/lithammer/fuzzysearch v1.1.2
github.com/robotn/gohook v0.30.5
gopkg.in/yaml.v2 v2.2.8
)
15 changes: 9 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
fyne.io/fyne v1.4.3 h1:356CnXCiYrrfaLGsB7qLK3c6ktzyh8WR05v/2RBu51I=
fyne.io/fyne v1.4.3/go.mod h1:8kiPBNSDmuplxs9WnKCkaWYqbcXFy0DeAzwa6PBO9Z8=
fyne.io/fyne/v2 v2.0.3 h1:qzd2uLLrAVrNeqnLY44QZCsMxZwjoo1my+lMzHicMXY=
fyne.io/fyne/v2 v2.0.3/go.mod h1:nNpgL7sZkDVLraGtQII2ArNRnnl6kHup/KfQRxIhbvs=
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ=
Expand All @@ -11,39 +9,42 @@ github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkK
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 h1:FDqhDm7pcsLhhWl1QtD8vlzI4mm59llRvNzrFg6/LAA=
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3/go.mod h1:CzM2G82Q9BDUvMTGHnXf/6OExw/Dz2ivDj48nVg7Lg8=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fyne-io/mobile v0.1.2/go.mod h1:/kOrWrZB6sasLbEy2JIvr4arEzQTXBTZGb3Y96yWbHY=
github.com/fyne-io/mobile v0.1.3-0.20210412090810-650a3139866a h1:3TAJhl8vXyli0tooKB0vd6gLCyBdWL4QEYbDoJpHEZk=
github.com/fyne-io/mobile v0.1.3-0.20210412090810-650a3139866a/go.mod h1:/kOrWrZB6sasLbEy2JIvr4arEzQTXBTZGb3Y96yWbHY=
github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 h1:SCYMcCJ89LjRGwEa0tRluNRiMjZHalQZrVrvTbPh+qw=
github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200625191551-73d3c3675aa3/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210410170116-ea3d685f79fb h1:T6gaWBvRzJjuOrdCtg8fXXjKai2xSDqWTcKFUPuw8Tw=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210410170116-ea3d685f79fb/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-vgo/robotgo v0.93.1 h1:bSuya586zK6/NpA5+mMPenzw4KlvbWGhLBISzGlEZoM=
github.com/go-vgo/robotgo v0.93.1/go.mod h1:HUCwEV5VvBtnX3Vh0EmlAkETEdcJKeHVmAPMmHaqT+A=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff h1:W71vTCKoxtdXgnm1ECDFkfQnpdqAO00zzGXLA5yaEX8=
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw=
github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc=
github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lithammer/fuzzysearch v1.1.2 h1:ePUtm14xKxbpCxozcFbIDRtvANxnVnE+RKpJUqkr2gA=
github.com/lithammer/fuzzysearch v1.1.2/go.mod h1:v6tYW/9kpfV6LNcweXdSjQsfCku/1M/oObmSox1fzP8=
github.com/lucor/goinfo v0.0.0-20200401173949-526b5363a13a/go.mod h1:ORP3/rB5IsulLEBwQZCJyyV6niqmI7P4EWSmkug+1Ng=
github.com/lxn/win v0.0.0-20201111105847-2a20daff6a55 h1:4BxFx5XCtXc+nFtXDGDW+Uu5sPtsAbvPh6RObj3fG9o=
github.com/lxn/win v0.0.0-20201111105847-2a20daff6a55/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
github.com/otiai10/gosseract v2.2.1+incompatible h1:Ry5ltVdpdp4LAa2bMjsSJH34XHVOV7XMi41HtzL8X2I=
github.com/otiai10/gosseract v2.2.1+incompatible/go.mod h1:XrzWItCzCpFRZ35n3YtVTgq5bLAhFIkascoRo8G32QE=
github.com/otiai10/mint v1.3.0 h1:Ady6MKVezQwHBkGzLFbrsywyp09Ah7rkmfjV3Bcr5uc=
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down Expand Up @@ -104,8 +105,9 @@ golang.org/x/sys v0.0.0-20210104204734-6f8348627aad h1:MCsdmFSdEd4UEa5TKS5JztCRH
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190808195139-e713427fea3f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
Expand All @@ -114,6 +116,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
Expand Down
220 changes: 197 additions & 23 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,218 @@ package main

import (
"fmt"
"math"
"os"
"path/filepath"
"sort"
"strings"

"fyne.io/fyne/app"
"fyne.io/fyne/container"
"fyne.io/fyne/widget"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
"github.com/go-vgo/robotgo"
"github.com/lithammer/fuzzysearch/fuzzy"
hook "github.com/robotn/gohook"
"gopkg.in/yaml.v2"
)

type snippet struct {
label string
content string
}

func main() {
fmt.Println("hi!")
// robotgo.TypeStr("Hello World")
go add()
snippets, snippetsText, err := loadSnippets()
if err != nil {
panic(err)
}

a := app.New()
w := a.NewWindow("Hello")
a.Settings().SetTheme(theme.DarkTheme())
var w fyne.Window
if drv, ok := fyne.CurrentApp().Driver().(desktop.Driver); ok {
w = drv.CreateSplashWindow()
} else {
w = a.NewWindow("")
}

list, entry := createSearchWidget(snippets,
snippetsText,
func(snippet *snippet) {
w.Hide()
typeSnippet(snippet.content)
},
func() {
w.Hide()
},
)

hello := widget.NewLabel("Hello Fyne!")
w.SetContent(container.NewVBox(
hello,
widget.NewButton("Hi!", func() {
robotgo.MoveMouse(100, 100)
}),
))
split := container.NewVSplit(entry, list)
split.Offset = 0
w.SetContent(split)
w.Resize(fyne.NewSize(400, 400))
w.Canvas().Focus(entry)
w.CenterOnScreen()

go listenForHotkeys(w)

w.ShowAndRun()
}

func add() {
fmt.Println("--- Please press ctrl + shift + q to stop hook ---")
robotgo.EventHook(hook.KeyDown, []string{"q", "ctrl", "shift"}, func(e hook.Event) {
fmt.Println("ctrl-shift-q")
robotgo.EventEnd()
})
func loadSnippets() ([]*snippet, []string, error) {
dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
bytes, err := os.ReadFile(filepath.Join(dir, "snippets.yml"))
if err != nil {
return nil, nil, err
}

var rawSnippets map[string]string
err = yaml.Unmarshal(bytes, &rawSnippets)
if err != nil {
return nil, nil, err
}

var snippets []*snippet
var snippetsText []string
for k, v := range rawSnippets {
snippets = append(snippets, &snippet{
label: k,
content: v,
})
snippetsText = append(snippetsText, fmt.Sprintf("%s: %s", k, v))
}
return snippets, snippetsText, nil
}

func createSearchWidget(snippets []*snippet, snippetsText []string, onSubmit func(snippet *snippet), onCancel func()) (*widget.List, *snippetEntry) {
filteredSnippets := snippets

list := widget.NewList(
func() int {
return len(filteredSnippets)
},
func() fyne.CanvasObject {
label := widget.NewLabel("tmpl lbl")
label.TextStyle.Bold = true
content := widget.NewLabel("tmpl content")
content.Wrapping = fyne.TextWrapBreak
return container.NewHBox(label, content)
},
func(id widget.ListItemID, item fyne.CanvasObject) {
container := item.(*fyne.Container)
label := container.Objects[0].(*widget.Label)
content := container.Objects[1].(*widget.Label)
label.SetText(filteredSnippets[id].label + ":")
content.SetText(strings.ReplaceAll(filteredSnippets[id].content, "\n", "\\n"))
ellipsis(container, content)
},
)

var selectedID widget.ListItemID = -1
list.OnSelected = func(id widget.ListItemID) {
selectedID = id
}
list.Select(0)

entry := newSnippetEntry()

resetSearch := func() {
entry.Text = ""
entry.OnChanged(entry.Text)
list.Select(0)
}

fmt.Println("--- Please press w---")
robotgo.EventHook(hook.KeyDown, []string{"w"}, func(e hook.Event) {
fmt.Println("omg w was pressed")
entry.onTypedKey = func(key *fyne.KeyEvent) {
if key.Name == "Down" {
list.Select((selectedID + 1) % len(filteredSnippets))
} else if key.Name == "Up" {
list.Select((len(filteredSnippets) + selectedID - 1) % len(filteredSnippets))
} else if key.Name == "Return" {
if selectedID >= 0 && selectedID < len(filteredSnippets) {
onSubmit(filteredSnippets[selectedID])
resetSearch()
}
} else if key.Name == "Escape" {
onCancel()
resetSearch()
}
}
entry.OnChanged = func(s string) {
ranked := fuzzy.RankFindFold(s, snippetsText)
sort.Sort(ranked)
filteredSnippets = make([]*snippet, 0)
for _, r := range ranked {
filteredSnippets = append(filteredSnippets, snippets[r.OriginalIndex])
}
list.Refresh()
list.Select(0)
}

return list, entry
}

func listenForHotkeys(w fyne.Window) {
robotgo.EventHook(hook.KeyDown, []string{"q", "alt"}, func(e hook.Event) {
w.Show()
// robotgo.EventEnd()
})

s := robotgo.EventStart()
<-robotgo.EventProcess(s)
}

func typeSnippet(content string) {
lines := strings.Split(content, "\n")
first := true
for _, l := range lines {
if !first {
robotgo.MicroSleep(100)
robotgo.KeyTap("enter")
}
robotgo.TypeStr(l)
first = false
}
}

type snippetEntry struct {
widget.Entry
onTypedKey func(key *fyne.KeyEvent)
}

func newSnippetEntry() *snippetEntry {
e := &snippetEntry{}
e.ExtendBaseWidget(e)
return e
}

func (e *snippetEntry) TypedKey(key *fyne.KeyEvent) {
e.Entry.TypedKey(key)
if e.onTypedKey != nil {
e.onTypedKey(key)
}
}

func ellipsis(container *fyne.Container, label *widget.Label) {
w := fyne.MeasureText(string(label.Text), theme.TextSize(), label.TextStyle).Width
if label.Position().X+w > container.Size().Width {
wellipsis := fyne.MeasureText(string("..."), theme.TextSize(), label.TextStyle).Width
wmax := container.Size().Width - wellipsis
wpc := float64(w) / float64(len(label.Text))
k := 0
for label.Position().X+w > wmax {
overlap := label.Position().X + w - wmax
overlapc := int(math.Ceil(math.Max(1, float64(overlap)/wpc)))
if overlapc > len(label.Text) {
break
}
label.Text = label.Text[:len(label.Text)-overlapc]
w = fyne.MeasureText(string(label.Text), theme.TextSize(), label.TextStyle).Width
k++
}
label.Text += "..."
label.Refresh()
}
}

0 comments on commit 35e3387

Please sign in to comment.