editor.l 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. (
  2. (def editor-running 1)
  3. (def buf (alloc-str 1024))
  4. (def find-prev (fn buf rune pos (do
  5. (let p pos)
  6. (while (and (gt p 0) (not (eq rune (get buf p))))
  7. (let p (- p 1)))
  8. (+ p 0)
  9. )))
  10. (def find-next (fn buf rune pos (do
  11. (let p pos)
  12. (while (and (lt p (size buf)) (not (eq rune (get buf p))))
  13. (let p (+ p 1)))
  14. (+ p 0)
  15. )))
  16. (def find-prev-ws (fn buf pos (do
  17. (let p (+ pos 0))
  18. (while (and (gt p 0) (not (or (eq 10 (get buf p)) (eq 32 (get buf p)))))
  19. (let p (- p 1)))
  20. (if (eq p 0) 0 (+ p 1))
  21. )))
  22. (def find-next-ws (fn buf pos (do
  23. (let p (+ pos 0))
  24. (while (and (lt p (size buf)) (not (or (eq 10 (get buf p)) (eq 32 (get buf p)))))
  25. (let p (+ p 1)))
  26. (+ p 0)
  27. )))
  28. (def copy (fn buf from to num (do
  29. (let i 0)
  30. (let c 0)
  31. ;(print (list "copy: " buf from to num))
  32. (if (lt from to)
  33. (do
  34. (let i (- num 1))
  35. (while (gt i -1) (do
  36. (let c (get buf (+ from i)))
  37. (put buf (+ to i) c)
  38. (let i (- i 1))
  39. )) 0)
  40. (do
  41. (let i 0)
  42. (while (lt i num) (do
  43. (let c (get buf (+ from i)))
  44. (put buf (+ to i) c)
  45. (let i (+ i 1))
  46. )) 0)
  47. )
  48. num
  49. )))
  50. ; fixme clobbered reg loading broken on x64?
  51. ; fixme use substr instead of mutation
  52. (def remove (fn buf pos (do
  53. (let p (+ pos 0))
  54. (let from (+ pos 1))
  55. (let num (- (size buf) pos))
  56. (copy buf from p num)
  57. (put buf (- (size buf) 1) 0)
  58. buf
  59. )))
  60. (def insert (fn buf pos k (do
  61. (let p (+ pos 0))
  62. (let to (+ pos 1))
  63. (let c (+ k 0))
  64. (let num (- (size buf) (+ pos 1)))
  65. (copy buf p to num)
  66. (put buf p c)
  67. buf
  68. )))
  69. (def buf-render-x 32)
  70. (def buf-render-y 32)
  71. (def cursor-char 32)
  72. (def cursor-x 0)
  73. (def cursor-y 0)
  74. (def last-num-lines 0)
  75. (def scroll-y 0)
  76. (def scroll-dirty 0)
  77. (def buf-render (fn cursor b (do
  78. (let lines (split b [0a]))
  79. (let i 0)
  80. (let y 0)
  81. (let ln (car lines))
  82. (let pos 0)
  83. (let nextpos 0)
  84. (let y buf-render-y)
  85. (let render-all 0)
  86. ; number of lines changed? then rerender
  87. (if (or scroll-dirty (not (eq last-num-lines (list-size lines)))) (do
  88. (let render-all 1)
  89. (boxfill minx miny maxx maxy 0xffff)
  90. (def scroll-dirty 0)
  91. )
  92. 0)
  93. (def last-num-lines (list-size lines))
  94. (let i 0)
  95. (while ln (do
  96. (let is-current-line 0)
  97. (let i (+ i 1))
  98. (let nextpos (+ 1 (+ pos (size ln))))
  99. (if (and (gt cursor (- pos 1)) (lt cursor (+ nextpos 1))) (do
  100. ; cursor is in this line
  101. (def term-y (+ y 0))
  102. (def cursor-x (- cursor pos))
  103. (def cursor-y (- (- i 1) scroll-y ))
  104. (def term-x (+ buf-render-x (* rune-spacing cursor-x)))
  105. (def cursor-char (get ln cursor-x))
  106. (let is-current-line 1)
  107. ; blank out the line
  108. ;(if only-current (do
  109. ; (boxfill buf-render-x term-y (- maxx buf-render-x) rune-h 0xffff)
  110. ;) 0)
  111. ) 0)
  112. ; this crashes arm
  113. ; (or is-current-line (not only-current))
  114. (if (or render-all is-current-line) (do
  115. (if (and (lt y maxy) (not (gt scroll-y i)))
  116. (blit-str ln buf-render-x y)
  117. 0)
  118. ) 0)
  119. (let pos (+ nextpos 0))
  120. (if (not (gt scroll-y i))
  121. (let y (+ y 16))
  122. 0)
  123. (let lines (cdr lines))
  124. (let ln (car lines))
  125. ))
  126. 0
  127. )))
  128. (def word-at (fn buf pos (do
  129. (let from (find-prev-ws buf pos))
  130. (let to (find-next-ws buf pos))
  131. (substr buf from (- to from))
  132. )))
  133. (def cursor 0)
  134. (def buf-dirty 0)
  135. (def backspace (fn (if (gt cursor 0) (do
  136. (remove buf (- cursor 1))
  137. (def cursor (- cursor 1))
  138. (def buf-dirty 1)
  139. ) 0)))
  140. (def repair-at-cursor (fn (do
  141. (print "repair-at-cursor")
  142. (blit-char (if (eq cursor-char 0) 32 cursor-char) term-x term-y)
  143. )))
  144. (def cursor-left (fn (do
  145. (repair-at-cursor)
  146. (def cursor (- cursor 1))
  147. (def buf-dirty 1)
  148. )))
  149. (def cursor-right (fn (do
  150. (repair-at-cursor)
  151. (def cursor (+ cursor 1))
  152. (def buf-dirty 1)
  153. )))
  154. (def scroll-speed 10)
  155. (def cursor-up (fn (do
  156. (repair-at-cursor)
  157. (def cursor (find-prev buf 10 (- cursor 1)))
  158. (if (and (lt cursor-y 5) (gt scroll-y 0)) (do
  159. (def scroll-y (- scroll-y scroll-speed))
  160. (if (lt scroll-y 0) (def scroll-y 0) 0)
  161. (def scroll-dirty 1)
  162. ) 0)
  163. (def buf-dirty 1)
  164. )))
  165. (def cursor-down (fn (do
  166. (repair-at-cursor)
  167. (let nextzero (find-next buf 0 (+ cursor 1)))
  168. (let nextnl (find-next buf 10 (+ cursor 1)))
  169. (def cursor (if (lt nextzero nextnl) cursor nextnl))
  170. (if (and (gt cursor-y 30) (lt scroll-y last-num-lines)) (do
  171. (def scroll-y (+ scroll-y scroll-speed))
  172. (if (gt scroll-y (- last-num-lines 1)) (def scroll-y (- last-num-lines 1)) 0)
  173. (def scroll-dirty 1)
  174. ) 0)
  175. (def buf-dirty 1)
  176. )))
  177. (def exit-editor (fn (do
  178. (print "exit-editor")
  179. (def editor-running 0)
  180. )))
  181. (def handle-editor-key (fn k (do
  182. (if (eq k 20) (cursor-right)
  183. (if (eq k 19) (cursor-left)
  184. (if (eq k 0x7f) (backspace)
  185. (if (eq k 17) (cursor-up)
  186. (if (eq k 18) (cursor-down)
  187. (if (eq k 27) (exit-editor)
  188. (if (and (gt k 0) (lt k 250))
  189. (do
  190. (print (list "handle-editor-key2" k))
  191. (def buf (concat buf " ")) ; room for new character
  192. (insert buf cursor (+ k 0))
  193. (def cursor (+ cursor 1))
  194. (def buf-dirty 1)
  195. ) 0)
  196. ))))))
  197. (if buf-dirty (do
  198. (buf-render cursor buf)
  199. (def buf-dirty 0)
  200. ) 0)
  201. 0
  202. )))
  203. (def handle-command-key (fn 0))
  204. (def edit (fn edit-buf (do
  205. (def buf edit-buf)
  206. (def editor-running 1)
  207. (def last-num-lines -1)
  208. (def cursor 0)
  209. (let blink 0)
  210. (clear)
  211. (gc)
  212. (def term-x buf-render-x)
  213. (def term-y buf-render-y)
  214. (def buf-dirty 1)
  215. (while (eq 1 editor-running) (do
  216. (let str (recv keyboard))
  217. (let k (get str 0))
  218. (handle-editor-key k)
  219. (if (lt cursor 0) (def cursor 0) 0)
  220. (if (gt cursor (size buf)) (def cursor (size buf)) 0)
  221. ; (print (list "term-x/y" term-x term-y))
  222. (if (gt blink 9)
  223. (blit-char 0x2588 term-x term-y)
  224. (do
  225. (blit-char (if (eq cursor-char 0) 32 cursor-char) term-x term-y)
  226. ))
  227. (let blink (% (+ blink 1) 20))
  228. (send scr 0)
  229. (gc)
  230. ))
  231. (concat buf "")
  232. )))
  233. (def edit-file (fn path (do
  234. (let content (load path))
  235. (edit content)
  236. )))
  237. (def edit-new (fn (do
  238. (edit (alloc-str 4096))
  239. )))
  240. )