action.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. package editor
  2. import(
  3. "strings"
  4. "strconv"
  5. "os"
  6. "github.com/zyedidia/rope"
  7. "golang.design/x/clipboard"
  8. )
  9. type ActionManager = struct {
  10. Common []Action
  11. Normal []Action
  12. Insert []Action
  13. Palette []Action
  14. }
  15. type Action = struct {
  16. Binding string
  17. Command string
  18. AskArgs bool
  19. Callback func(*Model, []string)
  20. }
  21. func DefaultActionManager() ActionManager {
  22. return ActionManager{
  23. Common: []Action{
  24. Action{
  25. Binding: "f12",
  26. Callback: func(m *Model, args []string) {
  27. m.Mode = ModeNormal
  28. },
  29. },
  30. Action{
  31. Binding: "left",
  32. Callback: func(m *Model, args []string) {
  33. if m.Mode == ModePalette {
  34. m.BM.PaletteBuffer.MoveHoriz(-1)
  35. } else {
  36. m.BM.Current().MoveHoriz(-1)
  37. }
  38. },
  39. },
  40. Action{
  41. Binding: "right",
  42. Callback: func(m *Model, args []string) {
  43. if m.Mode == ModePalette {
  44. m.BM.PaletteBuffer.MoveHoriz(1)
  45. } else {
  46. m.BM.Current().MoveHoriz(1)
  47. }
  48. },
  49. },
  50. Action{
  51. Binding: "up",
  52. Callback: func(m *Model, args []string) {
  53. if m.Mode != ModePalette {
  54. m.BM.Current().MoveVert(-1)
  55. }
  56. },
  57. },
  58. Action{
  59. Binding: "down",
  60. Callback: func(m *Model, args []string) {
  61. if m.Mode != ModePalette {
  62. m.BM.Current().MoveVert(1)
  63. }
  64. },
  65. },
  66. Action{
  67. Binding: "ctrl+q",
  68. Command: "q",
  69. AskArgs: true,
  70. Callback: func(m *Model, args []string) {
  71. m.Quit()
  72. },
  73. },
  74. Action{
  75. Binding: "ctrl+s",
  76. Command: "s",
  77. AskArgs: false,
  78. Callback: func(m *Model, args []string) {
  79. path := ""
  80. if len(args) < 1 || args[0] == "" {
  81. if m.BM.Current().Path == "" {
  82. m.Mode = ModeNormal
  83. m.BM.PaletteBuffer.Clear()
  84. m.BM.PaletteBuffer.Insert("moose.error:Missing filename argument for save")
  85. return
  86. }
  87. }
  88. if len(args) > 0 && args[0] != "" {
  89. m.BM.Current().Path = args[0]
  90. }
  91. path = m.BM.Current().Path
  92. data := []byte(m.BM.Current().String())
  93. err := os.WriteFile(path, data, 0644)
  94. if err != nil {
  95. m.Mode = ModeNormal
  96. m.BM.PaletteBuffer.Clear()
  97. m.BM.PaletteBuffer.Insert("moose.error:Could not save to file \"" + path + "\": " + err.Error())
  98. return
  99. }
  100. m.BM.PaletteBuffer.Clear()
  101. m.BM.PaletteBuffer.Insert("moose.info:Wrote " + strconv.Itoa(len(data)) + " bytes to \"" + path + "\"")
  102. return
  103. },
  104. },
  105. Action{
  106. Binding: "shift+ctrl+Rune[s]",
  107. Command: "s",
  108. AskArgs: true,
  109. },
  110. Action{
  111. Binding: "ctrl+e",
  112. Command: "e",
  113. AskArgs: true,
  114. Callback: func(m *Model, args []string) {
  115. if len(args) < 1 {
  116. m.Mode = ModeNormal
  117. m.BM.PaletteBuffer.Clear()
  118. m.BM.PaletteBuffer.Insert("moose.error:Did not specify path for edit")
  119. return
  120. }
  121. content, err := os.ReadFile(args[0])
  122. if err != nil {
  123. m.Mode = ModeNormal
  124. m.BM.PaletteBuffer.Clear()
  125. m.BM.PaletteBuffer.Insert("moose.error:Could not edit file \"" + args[0] + "\": " + err.Error())
  126. return
  127. }
  128. m.BM.Current().Clear()
  129. m.BM.Current().Rope = rope.New(content)
  130. m.BM.Current().LI.Rebuild(m.BM.Current().Rope)
  131. m.BM.Current().Path = args[0]
  132. },
  133. },
  134. },
  135. Normal: []Action{
  136. Action{
  137. Binding: "Rune[w]",
  138. Callback: func(m *Model, args []string) {
  139. m.Mode = ModeWrite
  140. },
  141. },
  142. Action{
  143. Binding: "Rune[q]",
  144. Callback: func(m *Model, args []string) {
  145. m.Mode = ModePalette
  146. m.BM.PaletteBuffer.Clear()
  147. m.BM.PaletteBuffer.Insert("/")
  148. },
  149. },
  150. Action{
  151. Binding: "Rune[f]",
  152. AskArgs: true,
  153. Callback: func(m *Model, args []string) {
  154. m.Mode = ModePalette
  155. m.BM.PaletteBuffer.Clear()
  156. m.BM.PaletteBuffer.Insert("?")
  157. },
  158. },
  159. Action{
  160. Binding: "Rune[v]",
  161. Command: "paste",
  162. AskArgs: false,
  163. Callback: func(m *Model, args []string) {
  164. text := clipboard.Read(clipboard.FmtText)
  165. if string(text) != "" {
  166. m.BM.Current().Insert(string(text))
  167. }
  168. },
  169. },
  170. },
  171. Insert: []Action{
  172. Action{
  173. Binding: "shift+up",
  174. Command: "TODO:",
  175. AskArgs: false,
  176. Callback: func(m *Model, args []string) {
  177. m.BM.Current().AddCursorVert(-1)
  178. },
  179. },
  180. Action{
  181. Binding: "shift+down",
  182. Command: "TODO:",
  183. AskArgs: false,
  184. Callback: func(m *Model, args []string) {
  185. m.BM.Current().AddCursorVert(1)
  186. },
  187. },
  188. Action{
  189. Binding: "esc",
  190. Command: "TODO:",
  191. AskArgs: false,
  192. Callback: func(m *Model, args []string) {
  193. m.BM.Current().Insert("test")
  194. },
  195. },
  196. Action{
  197. Binding: "tab",
  198. Command: "TODO:",
  199. AskArgs: false,
  200. Callback: func(m *Model, args []string) {
  201. for _ = range 4 {
  202. m.BM.Current().Insert(" ")
  203. }
  204. },
  205. },
  206. Action{
  207. Binding: "shift+tab",
  208. Command: "TODO:",
  209. AskArgs: false,
  210. Callback: func(m *Model, args []string) {
  211. // TODO: implement m.BM.Current().remove...
  212. },
  213. },
  214. Action{
  215. Binding: "backspace",
  216. Callback: func(m *Model, args []string) {
  217. m.BM.Current().Delete()
  218. },
  219. },
  220. Action{
  221. Binding: "enter",
  222. Callback: func(m *Model, args []string) {
  223. m.BM.Current().Insert("\n")
  224. },
  225. },
  226. },
  227. Palette: []Action{
  228. Action{
  229. Binding: "backspace",
  230. Callback: func(m *Model, args []string) {
  231. m.BM.PaletteBuffer.Delete()
  232. },
  233. },
  234. Action{
  235. Binding: "enter",
  236. Callback: func(m *Model, _ []string) {
  237. input := m.BM.PaletteBuffer.String()
  238. args := strings.Split(input, " ")
  239. if args[0] == "" {
  240. m.Mode = ModeNormal
  241. return
  242. }
  243. cmd := string([]rune(args[0])[1:])
  244. if strings.HasPrefix(args[0], "/") {
  245. for _, action := range append(m.AM.Common, append(m.AM.Normal, m.AM.Insert...)...) {
  246. if action.Callback == nil { continue }
  247. if action.Command != "" && cmd == action.Command {
  248. m.Mode = ModeNormal
  249. action.Callback(m, args[1:])
  250. return
  251. }
  252. }
  253. m.Mode = ModeNormal
  254. m.BM.PaletteBuffer.Clear()
  255. m.BM.PaletteBuffer.Insert("moose.error:Unknown command \"" + cmd + "\"")
  256. } else if strings.HasPrefix(args[0], "?") {
  257. m.Mode = ModeFind
  258. m.BM.PaletteBuffer.Clear()
  259. m.BM.PaletteBuffer.Insert("moose.error:Find mode unimplemented \"" + cmd + "\"")
  260. } else {
  261. m.Mode = ModeNormal
  262. m.BM.PaletteBuffer.Clear()
  263. m.BM.PaletteBuffer.Insert("moose.error:Unknown palette input \"" + cmd + "\"")
  264. }
  265. },
  266. },
  267. },
  268. }
  269. }