diff --git a/frontend/src/services.js b/frontend/src/services.js index c6d46b7..88da2e0 100644 --- a/frontend/src/services.js +++ b/frontend/src/services.js @@ -12,11 +12,19 @@ class TextProcessor { setCodeMirrorEditor(editor) { this._editor = editor; window.runtime.EventsOn("process-text-response", (data) => { + const cursorPos = this._editor.state.selection.main.head; + const appendInsertPos = this._appendInsertPos; + this._appendInsertPos = undefined; + let newSelection; const changes = data.output.map(span => { if (span.append) { + const insertAt = appendInsertPos !== undefined ? appendInsertPos : span.pos + span.len; + if (cursorPos === insertAt) { + newSelection = { anchor: insertAt + span.text.length }; + } return { - from: span.pos + span.len, - to: span.pos + span.len, + from: insertAt, + to: insertAt, insert: span.text, }; } else { @@ -27,7 +35,11 @@ class TextProcessor { }; } }); - this._editor.dispatch({ changes: changes }); + const transaction = { changes: changes }; + if (newSelection) { + transaction.selection = newSelection; + } + this._editor.dispatch(transaction); }); window.runtime.EventsOn("request-text-process", (data) => { this.runTextCommand(data.action); @@ -44,12 +56,14 @@ class TextProcessor { let inputs = []; if (shouldBeAll) { + this._appendInsertPos = this._editor.state.selection.main.head; inputs.push({ text: this._editor.state.doc.toString(), pos: 0, len: this._editor.state.doc.length, }); } else { + this._appendInsertPos = undefined; inputs = ranges.map(r => ({ text: this._editor.state.doc.slice(r.from, r.to).toString(), pos: r.from, diff --git a/go.mod b/go.mod index 4e48c53..9a8d136 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module dequoter go 1.25 require ( + github.com/google/uuid v1.6.0 github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f github.com/wailsapp/wails/v2 v2.10.2 gopkg.in/yaml.v3 v3.0.1 @@ -49,7 +50,6 @@ require ( github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/golang-jwt/jwt/v4 v4.5.2 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect github.com/labstack/echo/v4 v4.13.3 // indirect diff --git a/textfilters.go b/textfilters.go index fcd047f..1bd4334 100644 --- a/textfilters.go +++ b/textfilters.go @@ -14,6 +14,7 @@ import ( "text/template" + "github.com/google/uuid" "gopkg.in/yaml.v3" "ucl.lmika.dev/ucl" ) @@ -60,14 +61,25 @@ var TextFilters = map[string]TextProcessor{ return TextFilterResponse{Output: strings.ToLower(input)}, nil }, }, + "quote": { + Label: "String: Quote", + Filter: func(ctx context.Context, input string) (resp TextFilterResponse, err error) { + return TextFilterResponse{Output: strconv.Quote(input)}, nil + }, + }, "unquote": { Label: "String: Unquote", Filter: func(ctx context.Context, input string) (resp TextFilterResponse, err error) { - out, err := strconv.Unquote(input) + endNL := "" + if strings.HasSuffix(input, "\n") { + endNL = "\n" + } + + out, err := strconv.Unquote(strings.TrimSpace(input)) if err != nil { return TextFilterResponse{}, err } - return TextFilterResponse{Output: out}, nil + return TextFilterResponse{Output: out + endNL}, nil }, }, "join-lines-with-commas": { @@ -176,6 +188,20 @@ var TextFilters = map[string]TextProcessor{ }, }, + "uuid": { + Label: "Generate: UUID v4", + Filter: func(ctx context.Context, input string) (resp TextFilterResponse, err error) { + u, err := uuid.NewRandom() + if err != nil { + return TextFilterResponse{}, fmt.Errorf("failed to generate UUID: %w", err) + } + return TextFilterResponse{ + Output: u.String(), + Append: true, + }, nil + }, + }, + "lines": { Label: "Lines: Count", Analyze: func(ctx context.Context, input string) (result string, err error) {