Have got text transformations working
This commit is contained in:
parent
9f2fa96b92
commit
41daf7cfc9
33
app.go
33
app.go
|
@ -2,7 +2,10 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
"lmika.dev/pkg/modash/moslice"
|
||||
)
|
||||
|
||||
// App struct
|
||||
|
@ -22,6 +25,30 @@ func (a *App) startup(ctx context.Context) {
|
|||
}
|
||||
|
||||
// Greet returns a greeting for the given name
|
||||
func (a *App) Greet(name string) string {
|
||||
return fmt.Sprintf("Hello %s, It's show time!", name)
|
||||
func (a *App) ProcessText(req ProcessTextRequest) {
|
||||
filter, ok := TextFilters[req.Action]
|
||||
if !ok {
|
||||
log.Printf("Unknown filter: [%s]", req.Action)
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := moslice.MapWithError(req.Input, func(span TextSpan) (TextSpan, error) {
|
||||
outStr, err := filter(span.Text)
|
||||
if err != nil {
|
||||
return TextSpan{}, err
|
||||
}
|
||||
return TextSpan{
|
||||
Text: outStr,
|
||||
Pos: span.Pos,
|
||||
Len: span.Len,
|
||||
}, nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("Error running filter: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
runtime.EventsEmit(a.ctx, "process-text-response", ProcessTextResponse{
|
||||
Output: resp,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -15,10 +15,8 @@
|
|||
data-action="keyup.enter->commands#runCommand keydown.esc->commands#dismissDialog keyup->commands#handleKeyup">
|
||||
</div>
|
||||
<select multiple class="command-options" data-commands-target="commandSelect">
|
||||
<option value="double"><span class="option-label">Double quotes</span></option>
|
||||
<option value="single"><span class="option-label">Single</span></option>
|
||||
<option value="backtick"><span class="option-label">Backtick quotes</span></option>
|
||||
<option value="none"><span class="option-label">None</span></option>
|
||||
<option value="unquote"><span class="option-label">Unquote</span></option>
|
||||
<option value="format-json"><span class="option-label">Format JSON</span></option>
|
||||
</select>
|
||||
</div>
|
||||
</dialog>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
.cm-editor {
|
||||
height: 100%;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
dialog#command-dialog {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { Controller } from "@hotwired/stimulus"
|
||||
|
||||
export default class extends Controller {
|
||||
import { textProcessor } from "../services.js";
|
||||
|
||||
export class CommandsController extends Controller {
|
||||
static targets = [
|
||||
"commandInput",
|
||||
"commandSelect",
|
||||
|
@ -30,7 +32,7 @@ export default class extends Controller {
|
|||
runCommand(ev) {
|
||||
ev.preventDefault();
|
||||
|
||||
console.log("Do this: " + this.commandSelectTarget.value);
|
||||
textProcessor.runTextCommand(this.commandSelectTarget.value);
|
||||
this.element.close();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@ import {EditorView, basicSetup} from "codemirror";
|
|||
import {keymap} from "@codemirror/view";
|
||||
import { Application } from "@hotwired/stimulus";
|
||||
|
||||
import CommandsController from "./controllers/commands_controller.js";
|
||||
import { textProcessor } from "./services.js";
|
||||
import {CommandsController} from "./controllers/commands_controller.js";
|
||||
|
||||
const view = new EditorView({
|
||||
parent: document.querySelector("#app"),
|
||||
|
@ -27,4 +28,6 @@ const view = new EditorView({
|
|||
window.Stimulus = Application.start()
|
||||
Stimulus.register("commands", CommandsController);
|
||||
|
||||
textProcessor.setCodeMirrorEditor(view);
|
||||
|
||||
view.focus();
|
31
frontend/src/services.js
Normal file
31
frontend/src/services.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
import {ProcessText} from "../wailsjs/go/main/App";
|
||||
|
||||
class TextProcessor {
|
||||
setCodeMirrorEditor(editor) {
|
||||
this._editor = editor;
|
||||
window.runtime.EventsOn("process-text-response", (data) => {
|
||||
const changes = data.output.map(span => ({
|
||||
from: span.pos,
|
||||
to: span.pos + span.len,
|
||||
insert: span.text,
|
||||
}));
|
||||
this._editor.dispatch({ changes: changes });
|
||||
});
|
||||
}
|
||||
|
||||
runTextCommand(command) {
|
||||
if (this._editor === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessText({
|
||||
action: command,
|
||||
input: [
|
||||
{text: this._editor.state.doc.toString(), pos: 0, len: this._editor.state.doc.length}
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const textProcessor = new TextProcessor();
|
3
frontend/wailsjs/go/main/App.d.ts
vendored
3
frontend/wailsjs/go/main/App.d.ts
vendored
|
@ -1,4 +1,5 @@
|
|||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
import {main} from '../models';
|
||||
|
||||
export function Greet(arg1:string):Promise<string>;
|
||||
export function ProcessText(arg1:main.ProcessTextRequest):Promise<void>;
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
export function Greet(arg1) {
|
||||
return window['go']['main']['App']['Greet'](arg1);
|
||||
export function ProcessText(arg1) {
|
||||
return window['go']['main']['App']['ProcessText'](arg1);
|
||||
}
|
||||
|
|
53
frontend/wailsjs/go/models.ts
Executable file
53
frontend/wailsjs/go/models.ts
Executable file
|
@ -0,0 +1,53 @@
|
|||
export namespace main {
|
||||
|
||||
export class TextSpan {
|
||||
text: string;
|
||||
pos: number;
|
||||
len: number;
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new TextSpan(source);
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) source = JSON.parse(source);
|
||||
this.text = source["text"];
|
||||
this.pos = source["pos"];
|
||||
this.len = source["len"];
|
||||
}
|
||||
}
|
||||
export class ProcessTextRequest {
|
||||
action: string;
|
||||
input: TextSpan[];
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new ProcessTextRequest(source);
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) source = JSON.parse(source);
|
||||
this.action = source["action"];
|
||||
this.input = this.convertValues(source["input"], TextSpan);
|
||||
}
|
||||
|
||||
convertValues(a: any, classs: any, asMap: boolean = false): any {
|
||||
if (!a) {
|
||||
return a;
|
||||
}
|
||||
if (a.slice && a.map) {
|
||||
return (a as any[]).map(elem => this.convertValues(elem, classs));
|
||||
} else if ("object" === typeof a) {
|
||||
if (asMap) {
|
||||
for (const key of Object.keys(a)) {
|
||||
a[key] = new classs(a[key]);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
return new classs(a);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
9
go.mod
9
go.mod
|
@ -1,8 +1,13 @@
|
|||
module dequoter
|
||||
|
||||
go 1.23
|
||||
go 1.23.3
|
||||
|
||||
require github.com/wailsapp/wails/v2 v2.10.2
|
||||
toolchain go1.24.3
|
||||
|
||||
require (
|
||||
github.com/wailsapp/wails/v2 v2.10.2
|
||||
lmika.dev/pkg/modash v0.0.0-20250729120720-cdaa1c8abbe3
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bep/debounce v1.2.1 // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -79,3 +79,5 @@ golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
|||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
lmika.dev/pkg/modash v0.0.0-20250729120720-cdaa1c8abbe3 h1:EqYZdM6ui++F2NPdFCjKAboOr14eVTIIiRfngBgg/WA=
|
||||
lmika.dev/pkg/modash v0.0.0-20250729120720-cdaa1c8abbe3/go.mod h1:8NDl/yR1eCCEhip9FJlVuMNXIeaztQ0Ks/tizExFcTI=
|
||||
|
|
2
main.go
2
main.go
|
@ -17,7 +17,7 @@ func main() {
|
|||
|
||||
// Create application with options
|
||||
err := wails.Run(&options.App{
|
||||
Title: "dequoter",
|
||||
Title: "Dequoter",
|
||||
Width: 1024,
|
||||
Height: 768,
|
||||
AssetServer: &assetserver.Options{
|
||||
|
|
16
models.go
Normal file
16
models.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package main
|
||||
|
||||
type TextSpan struct {
|
||||
Text string `json:"text"`
|
||||
Pos int `json:"pos"`
|
||||
Len int `json:"len"`
|
||||
}
|
||||
|
||||
type ProcessTextRequest struct {
|
||||
Action string `json:"action"`
|
||||
Input []TextSpan `json:"input"`
|
||||
}
|
||||
|
||||
type ProcessTextResponse struct {
|
||||
Output []TextSpan `json:"output"`
|
||||
}
|
22
textfilters.go
Normal file
22
textfilters.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type TextFilter func(input string) (output string, err error)
|
||||
|
||||
var TextFilters = map[string]TextFilter{
|
||||
"unquote": func(input string) (output string, err error) {
|
||||
return strconv.Unquote(input)
|
||||
},
|
||||
"format-json": func(input string) (output string, err error) {
|
||||
var dst bytes.Buffer
|
||||
if err := json.Indent(&dst, []byte(input), "", " "); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return dst.String(), nil
|
||||
},
|
||||
}
|
Loading…
Reference in a new issue