jsmdcui 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/LICENSE +22 -0
  3. package/README.md +285 -0
  4. package/package.json +17 -0
  5. package/project_structure.txt +35 -0
  6. package/runmd.mjs +240 -0
  7. package/runtime/colorschemes/atom-dark.micro +33 -0
  8. package/runtime/colorschemes/bubblegum.micro +31 -0
  9. package/runtime/colorschemes/cmc-16.micro +47 -0
  10. package/runtime/colorschemes/cmc-tc.micro +43 -0
  11. package/runtime/colorschemes/darcula.micro +34 -0
  12. package/runtime/colorschemes/default.micro +1 -0
  13. package/runtime/colorschemes/dracula-tc.micro +49 -0
  14. package/runtime/colorschemes/dukedark-tc.micro +38 -0
  15. package/runtime/colorschemes/dukelight-tc.micro +38 -0
  16. package/runtime/colorschemes/dukeubuntu-tc.micro +38 -0
  17. package/runtime/colorschemes/geany.micro +29 -0
  18. package/runtime/colorschemes/gotham.micro +29 -0
  19. package/runtime/colorschemes/gruvbox-tc.micro +29 -0
  20. package/runtime/colorschemes/gruvbox.micro +26 -0
  21. package/runtime/colorschemes/material-tc.micro +36 -0
  22. package/runtime/colorschemes/monokai-dark.micro +28 -0
  23. package/runtime/colorschemes/monokai.micro +34 -0
  24. package/runtime/colorschemes/one-dark.micro +39 -0
  25. package/runtime/colorschemes/railscast.micro +37 -0
  26. package/runtime/colorschemes/simple.micro +33 -0
  27. package/runtime/colorschemes/solarized-tc.micro +31 -0
  28. package/runtime/colorschemes/solarized.micro +30 -0
  29. package/runtime/colorschemes/sunny-day.micro +29 -0
  30. package/runtime/colorschemes/twilight.micro +40 -0
  31. package/runtime/colorschemes/zenburn.micro +30 -0
  32. package/runtime/help/actions.md +161 -0
  33. package/runtime/help/cdp.md +119 -0
  34. package/runtime/help/colors.md +421 -0
  35. package/runtime/help/commands.md +161 -0
  36. package/runtime/help/copypaste.md +149 -0
  37. package/runtime/help/defaultkeys.md +148 -0
  38. package/runtime/help/help.md +285 -0
  39. package/runtime/help/keybindings.md +355 -0
  40. package/runtime/help/linter.md +90 -0
  41. package/runtime/help/options.md +709 -0
  42. package/runtime/help/plugins.md +544 -0
  43. package/runtime/help/tutorial.md +112 -0
  44. package/runtime/jsplugins/cdp/cdp-server.js +1161 -0
  45. package/runtime/jsplugins/cdp/cdp.js +192 -0
  46. package/runtime/jsplugins/chapter/chapter.js +108 -0
  47. package/runtime/jsplugins/diff/diff.js +46 -0
  48. package/runtime/jsplugins/example/example.js +110 -0
  49. package/runtime/jsplugins/linter/linter.js +281 -0
  50. package/runtime/plugins/autoclose/autoclose.lua +75 -0
  51. package/runtime/plugins/ftoptions/ftoptions.lua +17 -0
  52. package/runtime/plugins/literate/README.md +5 -0
  53. package/runtime/plugins/literate/literate.lua +55 -0
  54. package/runtime/plugins/status/help/status.md +21 -0
  55. package/runtime/plugins/status/status.lua +62 -0
  56. package/runtime/syntax/LICENSE +22 -0
  57. package/runtime/syntax/PowerShell.yaml +128 -0
  58. package/runtime/syntax/README.md +63 -0
  59. package/runtime/syntax/ada.yaml +43 -0
  60. package/runtime/syntax/apacheconf.yaml +59 -0
  61. package/runtime/syntax/arduino.yaml +101 -0
  62. package/runtime/syntax/asciidoc.yaml +51 -0
  63. package/runtime/syntax/asm.yaml +123 -0
  64. package/runtime/syntax/ats.yaml +99 -0
  65. package/runtime/syntax/awk.yaml +44 -0
  66. package/runtime/syntax/b.yaml +87 -0
  67. package/runtime/syntax/bat.yaml +57 -0
  68. package/runtime/syntax/c.yaml +60 -0
  69. package/runtime/syntax/caddyfile.yaml +23 -0
  70. package/runtime/syntax/cake.yaml +7 -0
  71. package/runtime/syntax/clojure.yaml +38 -0
  72. package/runtime/syntax/cmake.yaml +42 -0
  73. package/runtime/syntax/coffeescript.yaml +56 -0
  74. package/runtime/syntax/colortest.yaml +19 -0
  75. package/runtime/syntax/conky.yaml +17 -0
  76. package/runtime/syntax/cpp.yaml +91 -0
  77. package/runtime/syntax/crontab.yaml +36 -0
  78. package/runtime/syntax/crystal.yaml +72 -0
  79. package/runtime/syntax/csharp.yaml +52 -0
  80. package/runtime/syntax/css.yaml +44 -0
  81. package/runtime/syntax/csx.yaml +8 -0
  82. package/runtime/syntax/cuda.yaml +68 -0
  83. package/runtime/syntax/cython.yaml +52 -0
  84. package/runtime/syntax/d.yaml +121 -0
  85. package/runtime/syntax/dart.yaml +46 -0
  86. package/runtime/syntax/default.yaml +10 -0
  87. package/runtime/syntax/dockerfile.yaml +36 -0
  88. package/runtime/syntax/dot.yaml +29 -0
  89. package/runtime/syntax/elixir.yaml +30 -0
  90. package/runtime/syntax/elm.yaml +38 -0
  91. package/runtime/syntax/erb.yaml +42 -0
  92. package/runtime/syntax/erlang.yaml +45 -0
  93. package/runtime/syntax/fish.yaml +48 -0
  94. package/runtime/syntax/forth.yaml +34 -0
  95. package/runtime/syntax/fortran.yaml +64 -0
  96. package/runtime/syntax/freebsd-kernel.yaml +14 -0
  97. package/runtime/syntax/fsharp.yaml +48 -0
  98. package/runtime/syntax/gdscript.yaml +61 -0
  99. package/runtime/syntax/gemini.yaml +19 -0
  100. package/runtime/syntax/gentoo-ebuild.yaml +48 -0
  101. package/runtime/syntax/gentoo-etc-portage.yaml +23 -0
  102. package/runtime/syntax/git-commit.yaml +35 -0
  103. package/runtime/syntax/git-config.yaml +14 -0
  104. package/runtime/syntax/git-rebase-todo.yaml +19 -0
  105. package/runtime/syntax/gleam.yaml +69 -0
  106. package/runtime/syntax/glsl.yaml +26 -0
  107. package/runtime/syntax/gnuplot.yaml +15 -0
  108. package/runtime/syntax/go.yaml +62 -0
  109. package/runtime/syntax/godoc.yaml +17 -0
  110. package/runtime/syntax/golo.yaml +73 -0
  111. package/runtime/syntax/gomod.yaml +31 -0
  112. package/runtime/syntax/graphql.yaml +47 -0
  113. package/runtime/syntax/groff.yaml +30 -0
  114. package/runtime/syntax/groovy.yaml +111 -0
  115. package/runtime/syntax/haml.yaml +16 -0
  116. package/runtime/syntax/hare.yaml +52 -0
  117. package/runtime/syntax/haskell.yaml +52 -0
  118. package/runtime/syntax/hc.yaml +52 -0
  119. package/runtime/syntax/html.yaml +70 -0
  120. package/runtime/syntax/html4.yaml +25 -0
  121. package/runtime/syntax/html5.yaml +25 -0
  122. package/runtime/syntax/ini.yaml +23 -0
  123. package/runtime/syntax/inputrc.yaml +14 -0
  124. package/runtime/syntax/java.yaml +37 -0
  125. package/runtime/syntax/javascript.yaml +124 -0
  126. package/runtime/syntax/jinja2.yaml +19 -0
  127. package/runtime/syntax/json.yaml +39 -0
  128. package/runtime/syntax/jsonnet.yaml +92 -0
  129. package/runtime/syntax/julia.yaml +57 -0
  130. package/runtime/syntax/justfile.yaml +40 -0
  131. package/runtime/syntax/keymap.yaml +27 -0
  132. package/runtime/syntax/kickstart.yaml +16 -0
  133. package/runtime/syntax/kotlin.yaml +66 -0
  134. package/runtime/syntax/kvlang.yaml +67 -0
  135. package/runtime/syntax/ledger.yaml +14 -0
  136. package/runtime/syntax/lfe.yaml +17 -0
  137. package/runtime/syntax/lilypond.yaml +26 -0
  138. package/runtime/syntax/lisp.yaml +17 -0
  139. package/runtime/syntax/log.yaml +92 -0
  140. package/runtime/syntax/lua.yaml +111 -0
  141. package/runtime/syntax/mail.yaml +25 -0
  142. package/runtime/syntax/makefile.yaml +38 -0
  143. package/runtime/syntax/man.yaml +12 -0
  144. package/runtime/syntax/markdown.yaml +49 -0
  145. package/runtime/syntax/mc.yaml +23 -0
  146. package/runtime/syntax/meson.yaml +51 -0
  147. package/runtime/syntax/micro.yaml +34 -0
  148. package/runtime/syntax/mpdconf.yaml +13 -0
  149. package/runtime/syntax/msbuild.yaml +6 -0
  150. package/runtime/syntax/nanorc.yaml +16 -0
  151. package/runtime/syntax/nftables.yaml +30 -0
  152. package/runtime/syntax/nginx.yaml +22 -0
  153. package/runtime/syntax/nim.yaml +27 -0
  154. package/runtime/syntax/nix.yaml +32 -0
  155. package/runtime/syntax/nu.yaml +114 -0
  156. package/runtime/syntax/objc.yaml +60 -0
  157. package/runtime/syntax/ocaml.yaml +43 -0
  158. package/runtime/syntax/octave.yaml +83 -0
  159. package/runtime/syntax/odin.yaml +64 -0
  160. package/runtime/syntax/pascal.yaml +45 -0
  161. package/runtime/syntax/patch.yaml +14 -0
  162. package/runtime/syntax/peg.yaml +16 -0
  163. package/runtime/syntax/perl.yaml +58 -0
  164. package/runtime/syntax/php.yaml +60 -0
  165. package/runtime/syntax/pkg-config.yaml +12 -0
  166. package/runtime/syntax/po.yaml +12 -0
  167. package/runtime/syntax/pony.yaml +37 -0
  168. package/runtime/syntax/pov.yaml +21 -0
  169. package/runtime/syntax/privoxy-action.yaml +14 -0
  170. package/runtime/syntax/privoxy-config.yaml +10 -0
  171. package/runtime/syntax/privoxy-filter.yaml +12 -0
  172. package/runtime/syntax/proto.yaml +40 -0
  173. package/runtime/syntax/prql.yaml +84 -0
  174. package/runtime/syntax/puppet.yaml +22 -0
  175. package/runtime/syntax/python2.yaml +60 -0
  176. package/runtime/syntax/python3.yaml +80 -0
  177. package/runtime/syntax/r.yaml +32 -0
  178. package/runtime/syntax/raku.yaml +42 -0
  179. package/runtime/syntax/reST.yaml +18 -0
  180. package/runtime/syntax/renpy.yaml +15 -0
  181. package/runtime/syntax/rpmspec.yaml +43 -0
  182. package/runtime/syntax/ruby.yaml +73 -0
  183. package/runtime/syntax/rust.yaml +78 -0
  184. package/runtime/syntax/sage.yaml +60 -0
  185. package/runtime/syntax/scad.yaml +53 -0
  186. package/runtime/syntax/scala.yaml +33 -0
  187. package/runtime/syntax/sed.yaml +13 -0
  188. package/runtime/syntax/sh.yaml +69 -0
  189. package/runtime/syntax/sls.yaml +15 -0
  190. package/runtime/syntax/smalltalk.yaml +55 -0
  191. package/runtime/syntax/solidity.yaml +41 -0
  192. package/runtime/syntax/sql.yaml +35 -0
  193. package/runtime/syntax/stata.yaml +67 -0
  194. package/runtime/syntax/svelte.yaml +27 -0
  195. package/runtime/syntax/swift.yaml +103 -0
  196. package/runtime/syntax/systemd.yaml +16 -0
  197. package/runtime/syntax/tcl.yaml +18 -0
  198. package/runtime/syntax/terraform.yaml +87 -0
  199. package/runtime/syntax/tex.yaml +32 -0
  200. package/runtime/syntax/toml.yaml +56 -0
  201. package/runtime/syntax/twig.yaml +55 -0
  202. package/runtime/syntax/typescript.yaml +49 -0
  203. package/runtime/syntax/v.yaml +80 -0
  204. package/runtime/syntax/vala.yaml +26 -0
  205. package/runtime/syntax/verilog.yaml +60 -0
  206. package/runtime/syntax/vhdl.yaml +37 -0
  207. package/runtime/syntax/vi.yaml +31 -0
  208. package/runtime/syntax/vue.yaml +64 -0
  209. package/runtime/syntax/xml.yaml +37 -0
  210. package/runtime/syntax/xresources.yaml +14 -0
  211. package/runtime/syntax/yaml.yaml +34 -0
  212. package/runtime/syntax/yum.yaml +12 -0
  213. package/runtime/syntax/zig.yaml +52 -0
  214. package/runtime/syntax/zscript.yaml +72 -0
  215. package/runtime/syntax/zsh.yaml +52 -0
  216. package/single-exe/README.md +80 -0
  217. package/single-exe/assetsHelper.js +90 -0
  218. package/single-exe/assetsLoader.mjs +85 -0
  219. package/single-exe/compiled.js +149 -0
  220. package/single-exe/entry.mjs +9 -0
  221. package/single-exe/packAssets.sh +7 -0
  222. package/src/buffer/backup.js +160 -0
  223. package/src/buffer/buffer.js +126 -0
  224. package/src/buffer/fixed3-codec.js +140 -0
  225. package/src/buffer/loc.js +38 -0
  226. package/src/buffer/message.js +29 -0
  227. package/src/config/clean.js +172 -0
  228. package/src/config/colorscheme.js +99 -0
  229. package/src/config/config.js +122 -0
  230. package/src/config/defaults.js +109 -0
  231. package/src/cui/rpc.mjs +259 -0
  232. package/src/cui/server.mjs +116 -0
  233. package/src/display/ansi-style.js +60 -0
  234. package/src/highlight/highlighter.js +243 -0
  235. package/src/highlight/parser.js +225 -0
  236. package/src/index.js +8009 -0
  237. package/src/lua/engine.js +71 -0
  238. package/src/platform/archive.js +50 -0
  239. package/src/platform/clipboard.js +278 -0
  240. package/src/platform/commands.js +137 -0
  241. package/src/plugins/js-bridge.js +983 -0
  242. package/src/plugins/manager.js +674 -0
  243. package/src/runtime/assets.js +90 -0
  244. package/src/runtime/compiled.js +25 -0
  245. package/src/runtime/encodings.js +10 -0
  246. package/src/runtime/registry.js +134 -0
  247. package/src/screen/cell-buffer.js +81 -0
  248. package/src/screen/events.js +263 -0
  249. package/src/screen/screen.js +142 -0
  250. package/src/screen/vt100.js +571 -0
  251. package/src/shell/shell.js +70 -0
  252. package/testapp.md +55 -0
  253. package/tests/backup.test.js +133 -0
  254. package/tests/cmphex3b64.js +95 -0
  255. package/tests/pty-demo.js +492 -0
  256. package/tests/wv-client.js +96 -0
  257. package/tui +5 -0
  258. package/wui +5 -0
@@ -0,0 +1,192 @@
1
+ // No imports needed: `micro` is available as a global.
2
+
3
+ /*
4
+
5
+ # JS Plugin Documentation
6
+
7
+ Available hooks (register with micro.on(hookName, fn)):
8
+
9
+ Lifecycle (no args):
10
+ "preinit" — before plugins load
11
+ "init" — main plugin setup, register commands/actions here
12
+ "postinit" — after all plugins loaded
13
+
14
+ Buffer events:
15
+ "onBufferOpen" (buffer) — buffer opened (raw BufferModel, not pane adapter)
16
+ "onBufferClose" (buffer) — buffer closed (raw BufferModel)
17
+ "onSetActive" (bp) — pane became active (tab switch, close, etc.)
18
+ "onSave" (bp) — buffer saved
19
+
20
+ Input events:
21
+ "onRune" (bp, ch) — printable character inserted (ch is the string)
22
+
23
+ Cancellable hooks (return false to cancel the action):
24
+ "preBackspace" (bp) — before backspace; return false to block
25
+ "preInsertNewline" (bp) — before Enter/newline; return false to block
26
+
27
+ bp is a pane adapter with:
28
+ bp.Buf.Line(n) bp.Buf.LinesNum() bp.Buf.FileType()
29
+ bp.Buf.Insert(loc, text) bp.Buf.Replace(s, e, text)
30
+ bp.Cursor.X bp.Cursor.Y bp.Cursor.Loc bp.Cursor.HasSelection()
31
+ bp.Save() bp.Backspace() bp.CursorLeft/Right() bp.InsertNewline()
32
+
33
+ Flat buffer helpers (all 1-based line numbers, omit → cursor line):
34
+ micro.getLine(n?) micro.putLine(text, n?) micro.delLine(n?)
35
+ micro.getLines(from?, to?) micro.getLinesCount()
36
+ micro.getAllText() — entire buffer as one string (lines joined by "\n")
37
+ micro.putAllText(text) — replace entire buffer content; pushes undo
38
+ micro.getSelection() micro.putSelection(text)
39
+
40
+ Other micro APIs:
41
+ micro.CurPane() — returns pane adapter for active pane
42
+ micro.MakeCommand(name, fn) — register Ctrl+E command; fn(bp, args[])
43
+ args.raw = full original input string (bypass shellSplit)
44
+ e.g. for command "js 1+1": args.raw = "js 1+1", args.raw.slice(3) = "1+1"
45
+ micro.RegisterAction(name, fn) — register bindable action
46
+ micro.TermMessage(msg) — show msg in editor status row
47
+ micro.alert(msg) — suspend editor, print msg, wait for Enter
48
+ micro.Log(...args) — console.log passthrough
49
+ micro.GetOption(name) micro.SetOption(name, value)
50
+ micro.cmd.save() — call any editor command via proxy
51
+ micro.action.CursorUp() — run any registered action via proxy
52
+ micro.shell.CMD(...args) — run CMD interactively (same as Ctrl-B); async
53
+ e.g. await micro.shell.ls('-l')
54
+ await micro.shell.git('diff', '--stat')
55
+
56
+ */
57
+
58
+ micro.on("init", () => {
59
+ // Register a custom Ctrl+E command
60
+ micro.MakeCommand("cdp", async (bp, args) =>
61
+ {
62
+ const addrFlag = args.find(a => a.startsWith("--address="))?.slice("--address=".length);
63
+ const isPublic = args.includes("--public");
64
+ const port = parseInt(args.find(a => /^\d+$/.test(a))) || parseInt(Bun.env.CDP_PORT) || 9222;
65
+ const hostname = addrFlag ?? (isPublic ? "0.0.0.0" : "127.0.0.1");
66
+ const path = bp?.Buf?.Path || "(no path)";
67
+
68
+ if(!micro.cdpContext)
69
+ {
70
+ micro.cdpContext={
71
+ title(){
72
+ return path;
73
+ },
74
+ async evaluate(txt){
75
+ return await eval(txt);
76
+ },
77
+ async navigate(url){
78
+ await micro.cmd.open('-f', url);
79
+ },
80
+ async click(x,y,opt){
81
+ x=x||1 ; y=y||1 ;
82
+ await micro.cmd.goto(y+':'+x);
83
+ },
84
+ async scroll(dx,dy){
85
+ const pane = micro.CurPane();
86
+ if (!pane) return;
87
+
88
+ dx = toInteger(dx);
89
+ dy = toInteger(dy);
90
+
91
+ const line = Math.max(1, pane.Cursor.Y + dy + 1);
92
+ const column = Math.max(1, pane.Cursor.X + dx + 1);
93
+ await micro.cmd.goto(`${line}:${column}`);
94
+ },
95
+ async scrollTo(selector){
96
+ const pattern = selectorToSearchPattern(selector);
97
+ await micro.cmd.find(pattern);
98
+ },
99
+ goBack(){
100
+ micro.action.PrevTab();
101
+ },
102
+ goForward(){
103
+ micro.action.NextTab();
104
+ },
105
+ async type(text){
106
+ const bp = micro.CurPane();
107
+ if (!bp) return;
108
+ bp.Insert(text);
109
+ },
110
+ async press(key, options){
111
+ const bp = micro.CurPane();
112
+ if (!bp) return;
113
+
114
+ // modifiers bitmask: Alt=1, Ctrl=2, Meta=4, Shift=8
115
+ const mod = options?.modifiers ?? 0;
116
+ const ctrl = !!(mod & 2);
117
+ const shift = !!(mod & 8);
118
+
119
+ if (ctrl) {
120
+ const ctrlMap = {
121
+ a: () => micro.action.SelectAll(),
122
+ c: () => micro.action.Copy(),
123
+ x: () => micro.action.Cut(),
124
+ v: () => micro.action.Paste(),
125
+ z: () => micro.action.Undo(),
126
+ y: () => micro.action.Redo(),
127
+ s: () => micro.action.Save(),
128
+ };
129
+ const h = ctrlMap[key.toLowerCase()];
130
+ if (h) await h();
131
+ return;
132
+ }
133
+
134
+ const arrowAction = shift
135
+ ? { ArrowUp: 'SelectUp', ArrowDown: 'SelectDown', ArrowLeft: 'SelectLeft', ArrowRight: 'SelectRight' }
136
+ : { ArrowUp: 'CursorUp', ArrowDown: 'CursorDown', ArrowLeft: 'CursorLeft', ArrowRight: 'CursorRight' };
137
+
138
+ const keyMap = {
139
+ ...arrowAction,
140
+ Enter: () => micro.action.InsertNewline(),
141
+ Backspace: () => micro.action.Backspace(),
142
+ Delete: () => micro.action.Delete(),
143
+ Tab: () => micro.action.InsertTab(),
144
+ Escape: () => micro.action.Escape(),
145
+ Home: () => shift ? micro.action.SelectToStartOfLine() : micro.action.StartOfLine(),
146
+ End: () => shift ? micro.action.SelectToEndOfLine() : micro.action.EndOfLine(),
147
+ PageUp: () => shift ? micro.action.SelectPageUp() : micro.action.CursorPageUp(),
148
+ PageDown: () => shift ? micro.action.SelectPageDown() : micro.action.CursorPageDown(),
149
+ };
150
+
151
+ const entry = keyMap[key];
152
+ if (typeof entry === 'string') {
153
+ await micro.action[entry]();
154
+ } else if (typeof entry === 'function') {
155
+ await entry();
156
+ } else if (key.length === 1) {
157
+ bp.Insert(key);
158
+ }
159
+ },
160
+ }
161
+
162
+ let {CdpServer}=await import('./cdp-server.js');
163
+
164
+ micro.cdpPort = port;
165
+ CdpServer
166
+ .create(micro.cdpContext)
167
+ .listen(port, hostname);
168
+
169
+ const addr = isPublic ? `0.0.0.0:${port}` : `127.0.0.1:${port}`;
170
+ micro.TermMessage(`CDP@${addr} server running 伺服器啟動了`)
171
+
172
+ //await micro.alert(CdpServer)
173
+ } // server not running
174
+ else
175
+ {
176
+ micro.TermMessage(`CDP@${micro.cdpPort} already running a server 已有伺服器啟動`)
177
+ }
178
+
179
+
180
+ });
181
+
182
+ })
183
+
184
+ function selectorToSearchPattern(selector) {
185
+ const value = String(selector ?? "");
186
+ return value.startsWith("#") ? value.slice(1) : value;
187
+ }
188
+
189
+ function toInteger(value) {
190
+ const number = Number(value);
191
+ return Number.isFinite(number) ? Math.trunc(number) : 0;
192
+ }
@@ -0,0 +1,108 @@
1
+ // example.js — demonstrates the micro JS plugin API
2
+ // No imports needed: `micro` is available as a global.
3
+
4
+ /*
5
+
6
+ # JS Plugin Documentation
7
+
8
+ Available hooks (register with micro.on(hookName, fn)):
9
+
10
+ Lifecycle (no args):
11
+ "preinit" — before plugins load
12
+ "init" — main plugin setup, register commands/actions here
13
+ "postinit" — after all plugins loaded
14
+
15
+ Buffer events:
16
+ "onBufferOpen" (buffer) — buffer opened (raw BufferModel, not pane adapter)
17
+ "onBufferClose" (buffer) — buffer closed (raw BufferModel)
18
+ "onSetActive" (bp) — pane became active (tab switch, close, etc.)
19
+ "onSave" (bp) — buffer saved
20
+
21
+ Input events:
22
+ "onRune" (bp, ch) — printable character inserted (ch is the string)
23
+
24
+ Cancellable hooks (return false to cancel the action):
25
+ "preBackspace" (bp) — before backspace; return false to block
26
+ "preInsertNewline" (bp) — before Enter/newline; return false to block
27
+
28
+ bp is a pane adapter with:
29
+ bp.Buf.Line(n) bp.Buf.LinesNum() bp.Buf.FileType()
30
+ bp.Buf.Insert(loc, text) bp.Buf.Replace(s, e, text)
31
+ bp.Cursor.X bp.Cursor.Y bp.Cursor.Loc bp.Cursor.HasSelection()
32
+ bp.Save() bp.Backspace() bp.CursorLeft/Right() bp.InsertNewline()
33
+
34
+ Flat buffer helpers (all 1-based line numbers, omit → cursor line):
35
+ micro.getLine(n?) micro.putLine(text, n?) micro.delLine(n?)
36
+ micro.getLines(from?, to?) micro.getLinesCount()
37
+ micro.getAllText() — entire buffer as one string (lines joined by "\n")
38
+ micro.putAllText(text) — replace entire buffer content; pushes undo
39
+ micro.getSelection() micro.putSelection(text)
40
+
41
+ Other micro APIs:
42
+ micro.CurPane() — returns pane adapter for active pane
43
+ micro.MakeCommand(name, fn) — register Ctrl+E command; fn(bp, args[])
44
+ micro.RegisterAction(name, fn) — register bindable action
45
+ micro.TermMessage(msg) — show msg in editor status row
46
+ micro.alert(msg) — suspend editor, print msg, wait for Enter
47
+ micro.Log(...args) — console.log passthrough
48
+ micro.GetOption(name) micro.SetOption(name, value)
49
+ micro.cmd.save() — call any editor command via proxy
50
+ micro.action.CursorUp() — run any registered action via proxy
51
+ micro.shell.CMD(...args) — run CMD interactively (same as Ctrl-B); async
52
+ e.g. await micro.shell.ls('-l')
53
+ await micro.shell.git('diff', '--stat')
54
+
55
+ */
56
+
57
+ micro.on("init", () => {
58
+ // Register a custom Ctrl+E command
59
+
60
+
61
+ micro.MakeCommand("nextchapter", async (bp, args) =>
62
+ {
63
+ let fp=bp?.Buf?.Path
64
+ let i1=fp.lastIndexOf('/')- -1
65
+ let i2=fp.lastIndexOf('.')
66
+ let nb=fp.slice(i1,i2)
67
+ let nfp=fp.slice(0,i1)+(nb- -1)+fp.slice(i2)
68
+
69
+ await micro.cmd.open('-f',nfp)
70
+
71
+ /*
72
+ await micro.cmd.replaceall('曰','日')
73
+ await micro.cmd.replaceall('修土','修士')
74
+ await micro.cmd.replaceall('<p>','\n')
75
+ await micro.cmd.replaceall('</p>','\n')
76
+ await micro.cmd.goto(48)
77
+
78
+
79
+ micro.cmd.tts()
80
+ */
81
+
82
+ });
83
+
84
+ micro.MakeCommand("prevchapter", async (bp, args) =>
85
+ {
86
+ let fp=bp?.Buf?.Path
87
+ let i1=fp.lastIndexOf('/')- -1
88
+ let i2=fp.lastIndexOf('.')
89
+ let nb=fp.slice(i1,i2)
90
+ let nfp=fp.slice(0,i1)+(nb-1)+fp.slice(i2)
91
+
92
+ await micro.cmd.open('-f',nfp)
93
+
94
+ /*
95
+ await micro.cmd.replaceall('曰','日')
96
+ await micro.cmd.replaceall('修土','修士')
97
+ await micro.cmd.replaceall('<p>','\n')
98
+ await micro.cmd.replaceall('</p>','\n')
99
+ await micro.cmd.goto(48)
100
+
101
+ micro.cmd.tts()
102
+ */
103
+
104
+ });
105
+
106
+ });
107
+
108
+
@@ -0,0 +1,46 @@
1
+ // diff.js — JS port of the Lua diff plugin (Go parity)
2
+ // When diffgutter is enabled, fetches git HEAD content and sets it as the
3
+ // diff base so the editor can show added/modified/removed gutter markers.
4
+ //
5
+ // Go behavior (diff.lua):
6
+ // 1. Skip scratch buffers or buffers with no path.
7
+ // 2. Check the file exists on disk; skip if not.
8
+ // 3. Run: git -C <dir> show HEAD:./<file>
9
+ // 4. On git failure (not tracked / no commits): set diffBase = current file
10
+ // content — this produces no gutter markers (base == current).
11
+ // 5. On success: set diffBase = git HEAD content.
12
+
13
+ import { dirname, basename } from "node:path";
14
+ import { existsSync } from "node:fs";
15
+
16
+ const _hasGit = await Bun.which("git") !== null;
17
+
18
+ micro.on("onBufferOpen", async (buffer) => {
19
+ if (!_hasGit) return;
20
+ if (!buffer.Settings?.diffgutter) return;
21
+ if (buffer.Type?.Scratch) return;
22
+ const absPath = buffer.AbsPath || buffer.Path;
23
+ if (!absPath) return;
24
+
25
+ // Go: os.Stat check — only proceed if the file exists on disk
26
+ try { if (!existsSync(absPath)) return; } catch { return; }
27
+
28
+ const dir = dirname(absPath);
29
+ const file = basename(absPath);
30
+ try {
31
+ const proc = Bun.spawn(["git", "-C", dir, "show", `HEAD:./${file}`], {
32
+ stdio: ["ignore", "pipe", "pipe"],
33
+ });
34
+ const exitCode = await proc.exited;
35
+ if (exitCode === 0) {
36
+ const text = await new Response(proc.stdout).text();
37
+ buffer.SetDiffBase(text);
38
+ } else {
39
+ // Go: on git failure set diffBase = current content (no markers shown)
40
+ buffer.SetDiffBase(buffer.Bytes ? buffer.Bytes() : "");
41
+ }
42
+ } catch (e) {
43
+ // Go: on error set diffBase = current content (no markers shown)
44
+ buffer.SetDiffBase(buffer.Bytes ? buffer.Bytes() : "");
45
+ }
46
+ });
@@ -0,0 +1,110 @@
1
+ // example.js — demonstrates the micro JS plugin API
2
+ // No imports needed: `micro` is available as a global.
3
+
4
+ /*
5
+
6
+ # JS Plugin Documentation
7
+
8
+ Available hooks (register with micro.on(hookName, fn)):
9
+
10
+ Lifecycle (no args):
11
+ "preinit" — before plugins load
12
+ "init" — main plugin setup, register commands/actions here
13
+ "postinit" — after all plugins loaded
14
+
15
+ Buffer events:
16
+ "onBufferOpen" (buffer) — buffer opened (raw BufferModel, not pane adapter)
17
+ "onBufferClose" (buffer) — buffer closed (raw BufferModel)
18
+ "onSetActive" (bp) — pane became active (tab switch, close, etc.)
19
+ "onSave" (bp) — buffer saved
20
+
21
+ Input events:
22
+ "onRune" (bp, ch) — printable character inserted (ch is the string)
23
+
24
+ Cancellable hooks (return false to cancel the action):
25
+ "preBackspace" (bp) — before backspace; return false to block
26
+ "preInsertNewline" (bp) — before Enter/newline; return false to block
27
+
28
+ bp is a pane adapter with:
29
+ bp.Buf.Line(n) bp.Buf.LinesNum() bp.Buf.FileType()
30
+ bp.Buf.Insert(loc, text) bp.Buf.Replace(s, e, text)
31
+ bp.Cursor.X bp.Cursor.Y bp.Cursor.Loc bp.Cursor.HasSelection()
32
+ bp.Save() bp.Backspace() bp.CursorLeft/Right() bp.InsertNewline()
33
+
34
+ Flat buffer helpers (all 1-based line numbers, omit → cursor line):
35
+ micro.getLine(n?) micro.putLine(text, n?) micro.delLine(n?)
36
+ micro.getLines(from?, to?) micro.getLinesCount()
37
+ micro.getAllText() — entire buffer as one string (lines joined by "\n")
38
+ micro.putAllText(text) — replace entire buffer content; pushes undo
39
+ micro.getSelection() micro.putSelection(text)
40
+
41
+ Other micro APIs:
42
+ micro.CurPane() — returns pane adapter for active pane
43
+ micro.MakeCommand(name, fn) — register Ctrl+E command; fn(bp, args[])
44
+ args.raw = full original input string (bypass shellSplit)
45
+ e.g. for command "js 1+1": args.raw = "js 1+1", args.raw.slice(3) = "1+1"
46
+ micro.RegisterAction(name, fn) — register bindable action
47
+ micro.TermMessage(msg) — show msg in editor status row
48
+ micro.alert(msg) — suspend editor, print msg, wait for Enter
49
+ micro.Log(...args) — console.log passthrough
50
+ micro.GetOption(name) micro.SetOption(name, value)
51
+ micro.cmd.save() — call any editor command via proxy
52
+ micro.action.CursorUp() — run any registered action via proxy
53
+ micro.shell.CMD(...args) — run CMD interactively (same as Ctrl-B); async
54
+ e.g. await micro.shell.ls('-l')
55
+ await micro.shell.git('diff', '--stat')
56
+
57
+ */
58
+
59
+ micro.on("init", () => {
60
+ // Register a custom Ctrl+E command
61
+ micro.MakeCommand("showpath", async (bp, args) =>
62
+ {
63
+ //micro.TermMessage("Hello from JS plugin! Args: " + args.join(", "));
64
+
65
+ //await micro.alert(micro.getLine())
66
+ const path = bp?.Buf?.Path || "(no path)";
67
+ const loc = bp?.CursorLocation?.() || "+1.0:1";
68
+ await micro.alert(`${path}\n${loc}`)
69
+
70
+ });
71
+
72
+
73
+ micro.MakeCommand("js", async (bp, args) =>
74
+ {
75
+ // args.raw is the full original input string, e.g. "js console.log('hi')"
76
+ // slice(3) skips the "js " prefix (2-char name + 1 space)
77
+ const scriptText = args.raw?.slice(3) ?? args.join(" ");
78
+ await micro.alert(await eval(scriptText));
79
+ });
80
+
81
+
82
+ // greet: shows a message via micro.alert (leaves editor, shows text, Enter returns)
83
+ micro.MakeCommand("greet", async (bp, args) =>
84
+ {
85
+ const name = args.length ?
86
+ args.join(" ") : "world";
87
+
88
+ let s=Bun.markdown.ansi(
89
+ '# Hello\n- '+name
90
+ );
91
+
92
+ await micro.alert(s);
93
+ });
94
+
95
+ // Register a custom action (can be bound to a key in keybindings.json)
96
+ micro.RegisterAction("ExampleDuplicateAndComment", async () =>
97
+ {
98
+ await micro.action.DuplicateLine();
99
+ await micro.action.ToggleComment();
100
+ });
101
+ });
102
+
103
+ micro.on("onSave", (bp) =>
104
+ {
105
+ // bp is the BufPane adapter
106
+ // (same as Lua's bp arg)
107
+
108
+ const path = bp?.Buf?.Path || "(no path)";
109
+ //micro.Log("[example] saved:", path);
110
+ });