state_api.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package edit
  2. import (
  3. "src.elv.sh/pkg/cli"
  4. "src.elv.sh/pkg/cli/tk"
  5. "src.elv.sh/pkg/eval"
  6. "src.elv.sh/pkg/eval/vals"
  7. "src.elv.sh/pkg/eval/vars"
  8. )
  9. func insertAtDot(app cli.App, text string) {
  10. codeArea, ok := focusedCodeArea(app)
  11. if !ok {
  12. return
  13. }
  14. codeArea.MutateState(func(s *tk.CodeAreaState) {
  15. s.Buffer.InsertAtDot(text)
  16. })
  17. }
  18. func replaceInput(app cli.App, text string) {
  19. codeArea, ok := focusedCodeArea(app)
  20. if !ok {
  21. return
  22. }
  23. codeArea.MutateState(func(s *tk.CodeAreaState) {
  24. s.Buffer = tk.CodeBuffer{Content: text, Dot: len(text)}
  25. })
  26. }
  27. func initStateAPI(app cli.App, nb eval.NsBuilder) {
  28. // State API always operates on the root CodeArea widget
  29. codeArea := app.ActiveWidget().(tk.CodeArea)
  30. nb.AddGoFns(map[string]any{
  31. "insert-at-dot": func(s string) { insertAtDot(app, s) },
  32. "replace-input": func(s string) { replaceInput(app, s) },
  33. })
  34. setDot := func(v any) error {
  35. var dot int
  36. err := vals.ScanToGo(v, &dot)
  37. if err != nil {
  38. return err
  39. }
  40. codeArea.MutateState(func(s *tk.CodeAreaState) {
  41. s.Buffer.Dot = dot
  42. })
  43. return nil
  44. }
  45. getDot := func() any {
  46. return vals.FromGo(codeArea.CopyState().Buffer.Dot)
  47. }
  48. nb.AddVar("-dot", vars.FromSetGet(setDot, getDot))
  49. setCurrentCommand := func(v any) error {
  50. var content string
  51. err := vals.ScanToGo(v, &content)
  52. if err != nil {
  53. return err
  54. }
  55. replaceInput(app, content)
  56. return nil
  57. }
  58. getCurrentCommand := func() any {
  59. return vals.FromGo(codeArea.CopyState().Buffer.Content)
  60. }
  61. nb.AddVar("current-command", vars.FromSetGet(setCurrentCommand, getCurrentCommand))
  62. }