buninu-linux 0.14.57 → 0.16.59
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.
- package/LICENSES/linux-firmware/LICENCE.nvidia +131 -0
- package/LICENSES/linux-firmware/LICENSE.amdgpu +51 -0
- package/LICENSES/linux-firmware/LICENSE.amdisp +31 -0
- package/LICENSES/linux-firmware/LICENSE.i915 +39 -0
- package/LICENSES/linux-firmware/LICENSE.radeon +51 -0
- package/LICENSES/linux-firmware/LICENSE.xe +39 -0
- package/LICENSES/linux-firmware/WHENCE +10280 -0
- package/NOTICE.md +64 -46
- package/README.md +378 -87
- package/README.zh.md +2041 -0
- package/build-image.sh +10 -1
- package/build-uki.sh +3 -1
- package/fetch-alpine.sh +14 -0
- package/graphics.md +31 -0
- package/index.js +28 -11
- package/initramfs/bin/buninu-browser +4 -1
- package/initramfs/bin/buninu-land +1 -1
- package/initramfs/bin/bunterm +3 -3
- package/initramfs/bin/chroot +13 -0
- package/initramfs/bin/chvt +11 -0
- package/initramfs/bin/mount +4 -0
- package/initramfs/bin/umount +6 -0
- package/initramfs/bin/xdg-open +33 -0
- package/initramfs/buninu/CHANGELOG.md +66 -0
- package/initramfs/buninu/apps/bunmsh/CHANGELOG.md +4 -0
- package/initramfs/buninu/apps/bunmsh/package.json +1 -1
- package/initramfs/buninu/apps/bunmsh/src/main.js +1 -1
- package/initramfs/buninu/apps/jsgotty/LICENSES/MIT-jsmdcui.txt +22 -0
- package/initramfs/buninu/apps/jsgotty/NOTICE +5 -0
- package/initramfs/buninu/apps/jsgotty/README.en.md +61 -0
- package/initramfs/buninu/apps/jsgotty/README.md +61 -0
- package/initramfs/buninu/apps/jsgotty/client-modes.mjs +117 -0
- package/initramfs/buninu/apps/jsgotty/client.mjs +100 -10
- package/initramfs/buninu/apps/jsgotty/clipboard-powershell.js +18 -0
- package/initramfs/buninu/apps/jsgotty/clipboard.js +148 -0
- package/initramfs/buninu/apps/jsgotty/gotty.js +13 -0
- package/initramfs/buninu/apps/jsgotty/package-lock.json +2 -2
- package/initramfs/buninu/apps/jsgotty/package.json +1 -1
- package/initramfs/buninu/apps/jsgotty/static/css/index.css +14 -1
- package/initramfs/buninu/apps/jsgotty/static/index.html +1 -0
- package/initramfs/buninu/apps/jsgotty/static/js/gotty.js +187 -23
- package/initramfs/buninu/apps/jsgotty/static/js/kitty-keyboard.js +193 -0
- package/initramfs/buninu/apps/jsgotty/static/js/kitty.js +115 -7
- package/initramfs/buninu/apps/jsgotty/terminal-modes.js +332 -0
- package/initramfs/buninu/apps/jsgotty/tests/android-alt.test.js +115 -0
- package/initramfs/buninu/apps/jsgotty/tests/arrow-modifiers.test.js +80 -0
- package/initramfs/buninu/apps/jsgotty/tests/client-exit.test.mjs +45 -0
- package/initramfs/buninu/apps/jsgotty/tests/client-modes.test.mjs +105 -0
- package/initramfs/buninu/apps/jsgotty/tests/clipboard-browser.test.js +81 -0
- package/initramfs/buninu/apps/jsgotty/tests/clipboard.test.js +75 -0
- package/initramfs/buninu/apps/jsgotty/tests/kitty-keyboard-browser.test.js +53 -0
- package/initramfs/buninu/apps/jsgotty/tests/kitty-keyboard.test.js +102 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual/README.md +20 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual/keyboard-collector.cjs +55 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual/keyboard-debug.js +74 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual/kitty-keyboard.js +80 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual/zoom-collector.cjs +55 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual/zoom-debug.js +39 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual-touch-diagnostics.js +33 -0
- package/initramfs/buninu/apps/jsgotty/tests/manual-touch-diagnostics.mjs +22 -0
- package/initramfs/buninu/apps/jsgotty/tests/nested-cli-pty.test.mjs +116 -0
- package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes-browser.test.js +144 -0
- package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes.md +44 -0
- package/initramfs/buninu/apps/jsgotty/tests/reconnect-modes.test.js +166 -0
- package/initramfs/buninu/apps/jsgotty/tests/touch-drag-browser.test.js +106 -0
- package/initramfs/buninu/apps/jsgotty/tests/wheel-browser.test.js +60 -0
- package/initramfs/buninu/apps/jsmdcui/CHANGELOG.md +44 -0
- package/initramfs/buninu/apps/jsmdcui/package.json +1 -1
- package/initramfs/buninu/apps/jsmdcui/src/highlight/go-regexp.js +83 -0
- package/initramfs/buninu/apps/jsmdcui/src/highlight/highlighter.js +49 -62
- package/initramfs/buninu/apps/jsmdcui/src/highlight/parser.js +8 -5
- package/initramfs/buninu/apps/jsmdcui/tests/go-regexp.test.js +98 -0
- package/initramfs/buninu/apps/jsmdcui/tests/heading-ids.test.js +21 -16
- package/initramfs/buninu/apps/jsmdcui/tests/highlight-regions.test.js +73 -0
- package/initramfs/buninu/apps/jsmdcui/tests/id-collision.test.js +32 -9
- package/initramfs/buninu/apps/jsmdcui/tests/markdown-behavior.mjs +9 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/NORMAL-HTML.md +46 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/README.md +85 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/REPORT.md +328 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/compare.mjs +75 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/go.mod +5 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/normal-html-report.json +619 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/normal-html.html +9 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/oracle.go +49 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/report.json +2174 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/PowerShell.txt +39 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ada.txt +25 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/apacheconf.txt +49 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/arduino.txt +38 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/asciidoc.txt +33 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/asm.txt +77 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ats.txt +48 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/awk.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/b.txt +27 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/bat.txt +39 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/c.txt +34 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/caddyfile.txt +14 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cake.txt +7 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/clojure.txt +18 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cmake.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/coffeescript.txt +32 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/colortest.txt +19 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/conky.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cpp.txt +46 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/crontab.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/crystal.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/csharp.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/css.txt +19 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/csx.txt +7 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cuda.txt +37 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/cython.txt +22 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/d.txt +52 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dart.txt +27 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/default.txt +8 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dockerfile.txt +10 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/dot.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/elixir.txt +23 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/elm.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/erb.txt +32 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/erlang.txt +23 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fish.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/forth.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fortran.txt +40 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/freebsd-kernel.txt +10 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/fsharp.txt +27 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gdscript.txt +26 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gemini.txt +11 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gentoo-ebuild.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gentoo-etc-portage.txt +14 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-commit.txt +19 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-config.txt +11 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/git-rebase-todo.txt +10 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gleam.txt +44 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/glsl.txt +18 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gnuplot.txt +11 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/go.txt +33 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/godoc.txt +9 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/golo.txt +50 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/gomod.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/graphql.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/groff.txt +18 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/groovy.txt +42 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/haml.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/hare.txt +31 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/haskell.txt +26 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/hc.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html.txt +26 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html4.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/html5.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ini.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/inputrc.txt +14 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/java.txt +18 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/javascript.txt +41 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/jinja2.txt +13 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/json.txt +21 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/jsonnet.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/julia.txt +24 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/justfile.txt +26 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/keymap.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kickstart.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kotlin.txt +30 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/kvlang.txt +37 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ledger.txt +13 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lfe.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lilypond.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lisp.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/log.txt +45 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/lua.txt +48 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mail.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/makefile.txt +25 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/man.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/markdown.txt +21 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mc.txt +11 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/meson.txt +29 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/micro.txt +25 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/mpdconf.txt +13 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/msbuild.txt +7 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nanorc.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nftables.txt +22 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nginx.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nim.txt +23 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nix.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/nu.txt +92 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/objc.txt +36 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ocaml.txt +25 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/octave.txt +35 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/odin.txt +35 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pascal.txt +22 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/patch.txt +13 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/peg.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/perl.txt +27 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/php.txt +44 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pkg-config.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/po.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pony.txt +29 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/pov.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-action.txt +14 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-config.txt +10 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/privoxy-filter.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/proto.txt +22 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/prql.txt +42 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/puppet.txt +22 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/python2.txt +24 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/python3.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/r.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/raku.txt +19 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/reST.txt +18 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/renpy.txt +11 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/rpmspec.txt +31 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/ruby.txt +34 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/rust.txt +27 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sage.txt +24 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/scad.txt +23 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/scala.txt +16 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sed.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sh.txt +20 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sls.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/smalltalk.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/solidity.txt +26 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/sql.txt +35 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/stata.txt +32 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/svelte.txt +10 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/swift.txt +53 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/systemd.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/tcl.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/terraform.txt +28 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/tex.txt +15 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/toml.txt +31 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/twig.txt +29 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/typescript.txt +32 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/v.txt +47 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vala.txt +22 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/verilog.txt +37 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vhdl.txt +37 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vi.txt +17 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/vue.txt +29 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/xml.txt +14 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/xresources.txt +14 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/yaml.txt +19 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/yum.txt +12 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zig.txt +24 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zscript.txt +31 -0
- package/initramfs/buninu/apps/jsmdcui/tests/syntax-parity/samples/zsh.txt +21 -0
- package/initramfs/buninu/package.json +1 -1
- package/initramfs/init.js +19 -3
- package/initramfs/lib/bunterm/clipboard.js +14 -0
- package/initramfs/lib/bunterm/commands.js +37 -0
- package/initramfs/lib/bunterm/fps.js +38 -0
- package/initramfs/lib/bunterm/images.js +14 -6
- package/initramfs/lib/bunterm/input.js +58 -15
- package/initramfs/lib/bunterm/keyboard.js +62 -0
- package/initramfs/lib/bunterm/keycodes.js +104 -0
- package/initramfs/lib/bunterm/kitty-keyboard.cjs +195 -0
- package/initramfs/lib/bunterm/raw-protocol.js +111 -0
- package/initramfs/lib/bunterm/renderer.js +116 -28
- package/initramfs/lib/bunterm/selection.js +60 -0
- package/initramfs/lib/bunterm/terminal.js +157 -12
- package/initramfs/lib/bunterm/vt-menu.js +181 -0
- package/initramfs/lib/bunterm/vt.js +27 -1
- package/initramfs/lib/canvas.js +99 -0
- package/initramfs/lib/chvt.js +31 -0
- package/initramfs/lib/fbdev.js +32 -8
- package/initramfs/lib/gpu.js +77 -0
- package/initramfs/lib/mapped-frame.js +28 -0
- package/initramfs/lib/raw-image.js +71 -0
- package/initramfs/lib/xdg-open.js +42 -0
- package/initramfs/usr/share/doc/buninu-linux/bunterm.md +85 -11
- package/initramfs/usr/share/doc/buninu-linux/chvt.md +34 -0
- package/initramfs/usr/share/doc/buninu-linux/xdg-open.md +43 -0
- package/package.json +1 -1
- package/scripts/arch.js +7 -5
- package/scripts/arch.sh +5 -5
- package/scripts/build.js +16 -3
- package/scripts/fetch-gpu.js +105 -0
- package/scripts/fetch.js +11 -1
- package/scripts/gpu-firmware.json +22 -0
- package/scripts/modules.js +4 -1
- package/scripts/npm-packages.md +18 -17
- package/test/bunterm-fps.test.js +17 -0
- package/test/bunterm-image-bytes.test.js +15 -0
- package/test/bunterm-keyboard.test.js +116 -0
- package/test/bunterm-mapped-lifetime.test.js +147 -0
- package/test/bunterm-next-vt.test.js +9 -0
- package/test/bunterm-raw-protocol.test.js +39 -0
- package/test/bunterm-renderer.test.js +167 -0
- package/test/bunterm-selection.test.js +38 -0
- package/test/bunterm-vt-menu.test.js +178 -0
- package/test/chroot-bind.test.js +40 -2
- package/test/chvt.test.js +46 -0
- package/test/fbdev-sync.test.js +42 -0
- package/test/fetch-npm.test.js +2 -2
- package/test/gpu.test.js +155 -0
- package/test/image-size.test.js +17 -0
- package/test/manual-bunterm-image-paths.js +31 -0
- package/test/mount-libc-lifetime.test.js +50 -0
- package/test/no-gpu.test.js +43 -0
- package/test/readme-cli.test.js +29 -0
- package/test/stage-npm.test.js +11 -4
- package/test/xdg-open.test.js +55 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import {ownMapping, retainMapping} from "../mapped-frame.js";
|
|
3
|
+
// Buninu private extension; not a registered Kitty pixel format.
|
|
4
|
+
export const BGRA_FORMAT = 0x42475241;
|
|
5
|
+
export function preferredPixelFormat(display, littleEndian = new Uint8Array(new Uint32Array([1]).buffer)[0] === 1) {
|
|
6
|
+
if (!littleEndian || display?.bitsPerPixel !== 32) return 'png';
|
|
7
|
+
const f=display.fields;
|
|
8
|
+
const channel=(field,offset)=>field?.offset===offset&&field.length===8&&!field.msbRight;
|
|
9
|
+
const alpha=f?.transp;
|
|
10
|
+
if(alpha?.length && !channel(alpha,24))return 'png';
|
|
11
|
+
if(!channel(f?.green,8))return 'png';
|
|
12
|
+
if(channel(f?.red,16)&&channel(f?.blue,0))return 'bgra';
|
|
13
|
+
if(channel(f?.red,0)&&channel(f?.blue,16))return 'rgba';
|
|
14
|
+
return 'png';
|
|
15
|
+
}
|
|
16
|
+
// Only the native renderer advertises these formats; browser jsgotty is unchanged.
|
|
17
|
+
export function bgraParser(Base,display) {
|
|
18
|
+
return class extends Base {
|
|
19
|
+
constructor(...args) {
|
|
20
|
+
super(...args);
|
|
21
|
+
// The parser cache and renderer have independent lifetimes. Replacing a
|
|
22
|
+
// cache entry must not detach a frame still being drawn or handled.
|
|
23
|
+
this.images = new MappedImages(this.images);
|
|
24
|
+
this.mappingReads = [];
|
|
25
|
+
this.disposed = false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
dispose() {
|
|
29
|
+
if (this.disposed) return;
|
|
30
|
+
this.disposed = true;
|
|
31
|
+
this.images.clear();
|
|
32
|
+
this.transfers.clear();
|
|
33
|
+
this.pending = Buffer.alloc(0);
|
|
34
|
+
for (const release of this.mappingReads) release?.();
|
|
35
|
+
this.mappingReads = [];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
_readImageFile(control,payloadText,deleteAfterRead) {
|
|
39
|
+
// Only complete raw temporary frames are immutable producer handoffs.
|
|
40
|
+
// Ordinary files, compressed/partial transfers keep the copying reader.
|
|
41
|
+
const format=Number(control.f);
|
|
42
|
+
if(!deleteAfterRead || ![32,BGRA_FORMAT].includes(format) || control.O || control.S || control.o || typeof Bun.mmap!=="function")
|
|
43
|
+
return super._readImageFile(control,payloadText,deleteAfterRead);
|
|
44
|
+
const path=fs.realpathSync(Buffer.from(payloadText,"base64").toString("utf8"));
|
|
45
|
+
const stat=fs.statSync(path),w=Number(control.s),h=Number(control.v);
|
|
46
|
+
if(!this._isSafeTempGraphicsPath(path)||!stat.isFile()||!Number.isInteger(w)||!Number.isInteger(h)||w<1||h<1||w*h>16777216||stat.size!==w*h*4)
|
|
47
|
+
return super._readImageFile(control,payloadText,deleteAfterRead);
|
|
48
|
+
let bytes;
|
|
49
|
+
try { bytes=Bun.mmap(path,{shared:false}); }
|
|
50
|
+
catch { return super._readImageFile(control,payloadText,deleteAfterRead); }
|
|
51
|
+
// Keep the mapping through parsing, even for queries/errors that do not
|
|
52
|
+
// enter the image cache. Never truncate/reuse producer files.
|
|
53
|
+
this.mappingReads.push(ownMapping(bytes));
|
|
54
|
+
try { fs.unlinkSync(path); } catch {}
|
|
55
|
+
return Buffer.from(bytes.buffer,bytes.byteOffset,bytes.byteLength);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
_resolveImageData(control,payload) {
|
|
59
|
+
const bytes=super._resolveImageData(control,payload);
|
|
60
|
+
if(Number(control.f)===BGRA_FORMAT){
|
|
61
|
+
const w=Number(control.s),h=Number(control.v);
|
|
62
|
+
if(!Number.isInteger(w)||!Number.isInteger(h)||w<1||h<1||w*h>16777216||bytes.length!==w*h*4)
|
|
63
|
+
throw Error('Invalid BGRA dimensions or byte count');
|
|
64
|
+
}
|
|
65
|
+
return bytes;
|
|
66
|
+
}
|
|
67
|
+
_parsePacket(packet,cursor) {
|
|
68
|
+
if (this.disposed) return null;
|
|
69
|
+
const previousReads = this.mappingReads;
|
|
70
|
+
this.mappingReads = [];
|
|
71
|
+
try {
|
|
72
|
+
const result=super._parsePacket(packet,cursor);
|
|
73
|
+
const release = retainMapping(result?.image?.data);
|
|
74
|
+
// The consumer uses `using` while awaiting image handling/ACKs. This
|
|
75
|
+
// protects the result even if the parser cache is replaced or closed.
|
|
76
|
+
if (release) result[Symbol.dispose] = release;
|
|
77
|
+
if(result?.kind==='query'&&Number(result.control.f)===BGRA_FORMAT&&result.responseMessage==='OK')
|
|
78
|
+
result.responseMessage='OK Buninu1 '+preferredPixelFormat(display);
|
|
79
|
+
return result;
|
|
80
|
+
} finally {
|
|
81
|
+
for (const release of this.mappingReads) release?.();
|
|
82
|
+
this.mappingReads = previousReads;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
class MappedImages extends Map {
|
|
89
|
+
constructor(entries) {
|
|
90
|
+
super();
|
|
91
|
+
this.releases = new Map();
|
|
92
|
+
for (const [id, image] of entries) this.set(id, image);
|
|
93
|
+
}
|
|
94
|
+
set(id, image) {
|
|
95
|
+
const release = retainMapping(image?.data);
|
|
96
|
+
this.delete(id);
|
|
97
|
+
super.set(id, image);
|
|
98
|
+
if (release) this.releases.set(id, release);
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
delete(id) {
|
|
102
|
+
this.releases.get(id)?.();
|
|
103
|
+
this.releases.delete(id);
|
|
104
|
+
return super.delete(id);
|
|
105
|
+
}
|
|
106
|
+
clear() {
|
|
107
|
+
for (const release of this.releases.values()) release();
|
|
108
|
+
this.releases.clear();
|
|
109
|
+
super.clear();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {skiaImage} from '../raw-image.js';
|
|
1
2
|
// /lib/bunterm/renderer.js — paints an xterm.js headless buffer onto a Skia
|
|
2
3
|
// canvas as a grid of cells.
|
|
3
4
|
//
|
|
@@ -64,6 +65,7 @@ export class Renderer {
|
|
|
64
65
|
this.canvas = screen.canvas;
|
|
65
66
|
this.fonts = fonts;
|
|
66
67
|
this.fontSize = fontSize;
|
|
68
|
+
this.lineHeight = lineHeight;
|
|
67
69
|
this.theme = theme;
|
|
68
70
|
this.palette = buildPalette(theme);
|
|
69
71
|
this.foreground = parseColor(theme.foreground);
|
|
@@ -127,6 +129,30 @@ export class Renderer {
|
|
|
127
129
|
return font;
|
|
128
130
|
}
|
|
129
131
|
|
|
132
|
+
setFontSize(size) {
|
|
133
|
+
if (!Number.isInteger(size) || size < 6 || size > 96) throw new Error("font size must be an integer from 6 to 96");
|
|
134
|
+
if (size === this.fontSize) return;
|
|
135
|
+
for (const font of this.fontCache.values()) font.delete();
|
|
136
|
+
for (const paragraph of this.paragraphCache.values()) paragraph.delete();
|
|
137
|
+
this.fontCache.clear();
|
|
138
|
+
this.metricsCache.clear();
|
|
139
|
+
this.paragraphCache.clear();
|
|
140
|
+
this.fontSize = size;
|
|
141
|
+
const font = this.fontFor(this.fonts.regular, size), metrics = font.getMetrics();
|
|
142
|
+
this.cellWidth = Math.max(1, Math.round(font.getGlyphWidths(this.fonts.regular.getGlyphIDs("M"))[0]));
|
|
143
|
+
this.cellHeight = Math.max(1, Math.round((metrics.descent-metrics.ascent+(metrics.leading||0))*this.lineHeight));
|
|
144
|
+
this.columns = Math.max(1, Math.floor(this.screen.width/this.cellWidth));
|
|
145
|
+
this.rows = Math.max(1, Math.floor(this.screen.height/this.cellHeight));
|
|
146
|
+
this.offsetX = Math.floor((this.screen.width-this.columns*this.cellWidth)/2);
|
|
147
|
+
this.offsetY = Math.floor((this.screen.height-this.rows*this.cellHeight)/2);
|
|
148
|
+
this.rowHashes = new Int32Array(this.rows);
|
|
149
|
+
this.rawCoveredRows = new Set();
|
|
150
|
+
this.forcedRows.clear();
|
|
151
|
+
this.lastCursor = {x:-1,y:-1,visible:false};
|
|
152
|
+
this.lastPointer = null;
|
|
153
|
+
this.invalidate();
|
|
154
|
+
}
|
|
155
|
+
|
|
130
156
|
metricsFor(font) {
|
|
131
157
|
let metrics = this.metricsCache.get(font);
|
|
132
158
|
if (!metrics) {
|
|
@@ -214,7 +240,7 @@ export class Renderer {
|
|
|
214
240
|
width * this.cellWidth, height * this.cellHeight);
|
|
215
241
|
}
|
|
216
242
|
|
|
217
|
-
drawText(text, x, y, cells, color, { bold, italic, emoji }) {
|
|
243
|
+
drawText(text, x, y, cells, color, { bold, italic, emoji, align = "center" }) {
|
|
218
244
|
const { CanvasKit, canvas } = this;
|
|
219
245
|
const available = cells * this.cellWidth;
|
|
220
246
|
const paint = this.paintFor(color);
|
|
@@ -235,7 +261,7 @@ export class Renderer {
|
|
|
235
261
|
}
|
|
236
262
|
const metrics = this.metricsFor(font);
|
|
237
263
|
const baseline = y + (this.cellHeight - (metrics.descent - metrics.ascent)) / 2 - metrics.ascent;
|
|
238
|
-
canvas.drawGlyphs([glyph], [x + (available - advance) / 2, baseline], 0, 0, font, paint);
|
|
264
|
+
canvas.drawGlyphs([glyph], [align === "left" ? x : x + (available - advance) / 2, baseline], 0, 0, font, paint);
|
|
239
265
|
return;
|
|
240
266
|
}
|
|
241
267
|
// Grapheme clusters are shaped by the Paragraph API and cached.
|
|
@@ -272,13 +298,13 @@ export class Renderer {
|
|
|
272
298
|
const height = paragraph.getHeight();
|
|
273
299
|
canvas.save();
|
|
274
300
|
canvas.clipRect(CanvasKit.XYWHRect(x, y, available, this.cellHeight), CanvasKit.ClipOp.Intersect, false);
|
|
275
|
-
if (width > available) {
|
|
301
|
+
if (width > available && align !== "left") {
|
|
276
302
|
const scale = available / width;
|
|
277
303
|
canvas.translate(x, y + (this.cellHeight - height * scale) / 2);
|
|
278
304
|
canvas.scale(scale, scale);
|
|
279
305
|
canvas.drawParagraph(paragraph, 0, 0);
|
|
280
306
|
} else {
|
|
281
|
-
canvas.drawParagraph(paragraph, x + (available - width) / 2, y + (this.cellHeight - height) / 2);
|
|
307
|
+
canvas.drawParagraph(paragraph, align === "left" ? x : x + (available - width) / 2, y + (this.cellHeight - height) / 2);
|
|
282
308
|
}
|
|
283
309
|
canvas.restore();
|
|
284
310
|
}
|
|
@@ -322,15 +348,24 @@ export class Renderer {
|
|
|
322
348
|
}
|
|
323
349
|
}
|
|
324
350
|
|
|
325
|
-
drawRow(line, row) {
|
|
326
|
-
const
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
351
|
+
drawRow(line, row, hidden = []) {
|
|
352
|
+
const draw = (first, end) => {
|
|
353
|
+
if(end<=first)return;
|
|
354
|
+
this.canvas.drawRect(this.cellRect(first,row,end-first,1),this.paintFor(this.background));
|
|
355
|
+
if(!line)return;
|
|
356
|
+
for(let column=first;column<end;column++){
|
|
357
|
+
const cell=line.getCell(column);if(!cell)break;
|
|
358
|
+
this.drawCell(cell,column,row);
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
// Retain two boundary cells for wide glyphs and italic overhang. Interior
|
|
362
|
+
// pixels will be replaced by the opaque image; omit their background too.
|
|
363
|
+
let column=0;
|
|
364
|
+
for(const [first,end] of hidden.map(([a,b])=>[a+2,b-2]).sort((a,b)=>a[0]-b[0])){
|
|
365
|
+
draw(column,Math.min(this.columns,first));
|
|
366
|
+
column=Math.max(column,end);
|
|
333
367
|
}
|
|
368
|
+
draw(column,this.columns);
|
|
334
369
|
}
|
|
335
370
|
|
|
336
371
|
drawCursor(line, x, y) {
|
|
@@ -395,25 +430,54 @@ export class Renderer {
|
|
|
395
430
|
// screen pixels, from images.js, drawn over the text; `pointer` is the
|
|
396
431
|
// mouse position in pixels, drawn last. Returns true when anything was
|
|
397
432
|
// painted.
|
|
398
|
-
render(term, { cursor, images = [], pointer = null } = {}) {
|
|
433
|
+
render(term, { cursor, images = [], pointer = null, overlay = null } = {}) {
|
|
399
434
|
const buffer = term.buffer.active;
|
|
400
435
|
const top = buffer.viewportY;
|
|
401
436
|
const dirty = [];
|
|
437
|
+
// Only proven opaque, exact raw copies may hide text work. Partial-height
|
|
438
|
+
// rows, scaling, transparency and unsupported layouts remain unchanged.
|
|
439
|
+
const coveredRows = new Set(), coveredSpans = new Map();
|
|
440
|
+
const previousSpans = this.rawCoveredSpans ?? new Map();
|
|
441
|
+
const previouslyCovered = this.rawCoveredRows ?? new Set();
|
|
442
|
+
for (const {image, rect, source} of images) {
|
|
443
|
+
const bounds = source || [0, 0, image.width(), image.height()];
|
|
444
|
+
if (!this.screen.canDrawRawImage?.(image, rect, bounds)) continue;
|
|
445
|
+
const left=Math.max(0,Math.ceil((rect[0]-this.offsetX)/this.cellWidth));
|
|
446
|
+
const right=Math.min(this.columns,Math.floor((rect[2]-this.offsetX)/this.cellWidth));
|
|
447
|
+
const first = Math.max(0, Math.ceil((rect[1] - this.offsetY) / this.cellHeight));
|
|
448
|
+
const end = Math.min(this.rows, Math.floor((rect[3] - this.offsetY) / this.cellHeight));
|
|
449
|
+
for (let row = first; row < end; row++) {
|
|
450
|
+
if(left===0 && right===this.columns)coveredRows.add(row);
|
|
451
|
+
else if(right-left>4){
|
|
452
|
+
const spans=coveredSpans.get(row)??[];spans.push([left,right]);coveredSpans.set(row,spans);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
402
456
|
for (let row = 0; row < this.rows; row++) {
|
|
403
457
|
const line = buffer.getLine(top + row);
|
|
404
|
-
const hash = line ? this.rowHash(line, this.columns) : 0;
|
|
405
|
-
if (this.dirtyAll || hash !== this.rowHashes[row] || this.forcedRows.has(row)
|
|
458
|
+
const hash = coveredRows.has(row) ? this.rowHashes[row] : line ? this.rowHash(line, this.columns) : 0;
|
|
459
|
+
if (this.dirtyAll || hash !== this.rowHashes[row] || this.forcedRows.has(row)
|
|
460
|
+
|| coveredRows.has(row) !== previouslyCovered.has(row)
|
|
461
|
+
|| (coveredSpans.get(row)?.length??0)!==(previousSpans.get(row)?.length??0)
|
|
462
|
+
|| coveredSpans.get(row)?.some(([a,b],i)=>a!==previousSpans.get(row)?.[i]?.[0]||b!==previousSpans.get(row)?.[i]?.[1])) {
|
|
406
463
|
dirty.push(row);
|
|
407
464
|
this.rowHashes[row] = hash;
|
|
408
465
|
}
|
|
409
466
|
}
|
|
467
|
+
this.rawCoveredRows = coveredRows;
|
|
468
|
+
this.rawCoveredSpans = coveredSpans;
|
|
410
469
|
this.forcedRows.clear();
|
|
470
|
+
const localPointer = Boolean(this.screen.saveRegion && this.screen.restoreRegion);
|
|
471
|
+
const pointerChanged = this.lastPointer?.x !== pointer?.x || this.lastPointer?.y !== pointer?.y;
|
|
472
|
+
const cursorChanged = this.lastCursor.x !== (cursor?.x ?? -1)
|
|
473
|
+
|| this.lastCursor.y !== (cursor?.y ?? -1)
|
|
474
|
+
|| this.lastCursor.visible !== Boolean(cursor?.visible);
|
|
411
475
|
const cursorRows = new Set();
|
|
412
|
-
if (this.lastCursor.visible) cursorRows.add(this.lastCursor.y);
|
|
413
|
-
if (cursor?.visible) cursorRows.add(cursor.y);
|
|
476
|
+
if ((!localPointer || cursorChanged) && this.lastCursor.visible) cursorRows.add(this.lastCursor.y);
|
|
477
|
+
if ((!localPointer || cursorChanged) && cursor?.visible) cursorRows.add(cursor.y);
|
|
414
478
|
// Wherever the pointer was and is has to be repainted: the text under it
|
|
415
479
|
// has not changed, so no row hash would say so.
|
|
416
|
-
for (const position of [this.lastPointer, pointer]) {
|
|
480
|
+
for (const position of localPointer ? [] : [this.lastPointer, pointer]) {
|
|
417
481
|
if (!position) continue;
|
|
418
482
|
const [first, last] = this.pointerRows(position);
|
|
419
483
|
for (let row = Math.max(0, first); row < Math.min(this.rows, last); row++) cursorRows.add(row);
|
|
@@ -421,19 +485,35 @@ export class Renderer {
|
|
|
421
485
|
for (const row of cursorRows) {
|
|
422
486
|
if (row >= 0 && row < this.rows && !dirty.includes(row)) dirty.push(row);
|
|
423
487
|
}
|
|
488
|
+
if (!dirty.length && !this.dirtyAll && (!localPointer || !pointerChanged)) return false;
|
|
489
|
+
if (this.pointerBackground) {
|
|
490
|
+
this.screen.restoreRegion(this.pointerBackground);
|
|
491
|
+
this.pointerBackground = null;
|
|
492
|
+
}
|
|
424
493
|
if (this.dirtyAll) {
|
|
425
494
|
this.canvas.clear(this.CanvasKit.Color(this.background[0], this.background[1], this.background[2]));
|
|
426
495
|
}
|
|
427
496
|
this.dirtyAll = false;
|
|
428
|
-
if (!dirty.length) return false;
|
|
429
497
|
dirty.sort((a, b) => a - b);
|
|
430
|
-
for (const row of dirty)
|
|
431
|
-
|
|
498
|
+
for (const row of dirty) {
|
|
499
|
+
if (!coveredRows.has(row)) this.drawRow(buffer.getLine(top + row), row, coveredSpans.get(row));
|
|
500
|
+
}
|
|
501
|
+
if (cursor?.visible && !coveredRows.has(cursor.y) && dirty.includes(cursor.y)) {
|
|
432
502
|
this.drawCursor(buffer.getLine(top + cursor.y), cursor.x, cursor.y);
|
|
433
503
|
}
|
|
434
504
|
this.lastCursor = { x: cursor?.x ?? -1, y: cursor?.y ?? -1, visible: Boolean(cursor?.visible) };
|
|
435
|
-
if (images.length) this.drawImages(images, dirty);
|
|
436
|
-
if (
|
|
505
|
+
if (images.length && dirty.length) this.drawImages(images, dirty);
|
|
506
|
+
if (overlay && dirty.length) overlay();
|
|
507
|
+
if (pointer) {
|
|
508
|
+
if (localPointer) {
|
|
509
|
+
const size = Math.max(10, Math.round(this.fontSize * 0.9));
|
|
510
|
+
// Include the mitered outline and anti-aliasing outside the arrow path.
|
|
511
|
+
const padding = Math.ceil(Math.max(1, size / 8) * 2) + 2;
|
|
512
|
+
this.pointerBackground = this.screen.saveRegion(pointer.x - padding, pointer.y - padding,
|
|
513
|
+
pointer.x + size * 0.72 + padding, pointer.y + size * 1.08 + padding);
|
|
514
|
+
}
|
|
515
|
+
this.drawPointer(pointer);
|
|
516
|
+
}
|
|
437
517
|
this.lastPointer = pointer ? { x: pointer.x, y: pointer.y } : null;
|
|
438
518
|
this.screen.flush();
|
|
439
519
|
return true;
|
|
@@ -442,16 +522,24 @@ export class Renderer {
|
|
|
442
522
|
// Redraws the parts of image placements that intersect the repainted rows.
|
|
443
523
|
drawImages(images, dirtyRows) {
|
|
444
524
|
const { CanvasKit, canvas } = this;
|
|
525
|
+
const bands = [];
|
|
526
|
+
for (const row of dirtyRows) {
|
|
527
|
+
const top = this.offsetY + row * this.cellHeight, bottom = top + this.cellHeight;
|
|
528
|
+
const last = bands.at(-1);
|
|
529
|
+
if (last && last[1] === top) last[1] = bottom;
|
|
530
|
+
else bands.push([top, bottom]);
|
|
531
|
+
}
|
|
445
532
|
for (const { image, rect, source } of images) {
|
|
446
533
|
const [left, top, right, bottom] = rect;
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
534
|
+
if (!bands.some(([y0, y1]) => bottom > y0 && top < y1)) continue;
|
|
535
|
+
const bounds = source || [0, 0, image.width(), image.height()];
|
|
536
|
+
if (this.screen.drawOpaqueImage?.(image, rect, bounds, bands)) continue;
|
|
537
|
+
const sourceRect = CanvasKit.LTRBRect(...bounds);
|
|
538
|
+
for (const [rowTop, rowBottom] of bands) {
|
|
451
539
|
if (bottom <= rowTop || top >= rowBottom) continue;
|
|
452
540
|
canvas.save();
|
|
453
541
|
canvas.clipRect(CanvasKit.LTRBRect(0, rowTop, this.screen.width, rowBottom), CanvasKit.ClipOp.Intersect, false);
|
|
454
|
-
canvas.drawImageRectOptions(image, sourceRect, CanvasKit.LTRBRect(left, top, right, bottom),
|
|
542
|
+
canvas.drawImageRectOptions(skiaImage(image), sourceRect, CanvasKit.LTRBRect(left, top, right, bottom),
|
|
455
543
|
CanvasKit.FilterMode.Linear, CanvasKit.MipmapMode.Linear, null);
|
|
456
544
|
canvas.restore();
|
|
457
545
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Coordinates are buffer cells, not UTF-16 indices. Endpoints include a whole
|
|
2
|
+
// grapheme, even when the mouse hits the continuation cell of a wide character.
|
|
3
|
+
export function createSelection(term, renderer, changed) {
|
|
4
|
+
let anchor = null, end = null, dragging = false;
|
|
5
|
+
const clear = () => { if (anchor) { anchor = end = null; dragging = false; changed(); } };
|
|
6
|
+
const point = report => {
|
|
7
|
+
const x = Math.max(0, Math.min(term.cols - 1, Math.floor((report.x - renderer.offsetX) / renderer.cellWidth)));
|
|
8
|
+
const y = term.buffer.active.viewportY + Math.max(0, Math.min(term.rows - 1,
|
|
9
|
+
Math.floor((report.y - renderer.offsetY) / renderer.cellHeight)));
|
|
10
|
+
return {x,y};
|
|
11
|
+
};
|
|
12
|
+
const bounds = () => {
|
|
13
|
+
if (!anchor) return null;
|
|
14
|
+
let [a,b] = anchor.y < end.y || anchor.y === end.y && anchor.x <= end.x ? [anchor,end] : [end,anchor];
|
|
15
|
+
const first = term.buffer.active.getLine(a.y), last = term.buffer.active.getLine(b.y);
|
|
16
|
+
let start = a.x, stop = b.x;
|
|
17
|
+
if (first?.getCell(start)?.getWidth() === 0) start = Math.max(0,start-1);
|
|
18
|
+
if (last?.getCell(stop)?.getWidth() === 0) stop = Math.max(0,stop-1);
|
|
19
|
+
stop += Math.max(1,last?.getCell(stop)?.getWidth() || 1);
|
|
20
|
+
return {a:{x:start,y:a.y},b:{x:stop,y:b.y}};
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
clear,
|
|
24
|
+
stop() { dragging = false; },
|
|
25
|
+
get active() { return !!anchor; },
|
|
26
|
+
pointer(report) {
|
|
27
|
+
if (term._core?.coreMouseService?.areMouseEventsActive) { clear(); return false; }
|
|
28
|
+
if (report.pressed.includes("left")) { anchor = end = point(report); dragging = true; changed(); }
|
|
29
|
+
if (dragging && (report.moved || report.released.includes("left"))) { end = point(report); changed(); }
|
|
30
|
+
if (report.released.includes("left")) dragging = false;
|
|
31
|
+
return true;
|
|
32
|
+
},
|
|
33
|
+
text() {
|
|
34
|
+
const range = bounds();
|
|
35
|
+
if (!range) return "";
|
|
36
|
+
const {a,b} = range;
|
|
37
|
+
let text = "";
|
|
38
|
+
for (let y = a.y; y <= b.y; y++) {
|
|
39
|
+
const line = term.buffer.active.getLine(y);
|
|
40
|
+
if (!line) continue;
|
|
41
|
+
const start = y === a.y ? a.x : 0, stop = y === b.y ? b.x : term.cols;
|
|
42
|
+
if (y > a.y && !line.isWrapped) text += "\n";
|
|
43
|
+
// Wrapped rows join without a newline or lost meaningful spaces.
|
|
44
|
+
const nextWrapped = y < b.y && term.buffer.active.getLine(y + 1)?.isWrapped;
|
|
45
|
+
text += line.translateToString(!nextWrapped, start, stop);
|
|
46
|
+
}
|
|
47
|
+
return text;
|
|
48
|
+
},
|
|
49
|
+
draw() {
|
|
50
|
+
const range = bounds();
|
|
51
|
+
if (!range) return;
|
|
52
|
+
const {a,b} = range, top = term.buffer.active.viewportY;
|
|
53
|
+
for (let y = Math.max(a.y,top); y <= Math.min(b.y,top+term.rows-1); y++) {
|
|
54
|
+
const start = y === a.y ? a.x : 0, stop = y === b.y ? b.x : term.cols;
|
|
55
|
+
renderer.canvas.drawRect(renderer.cellRect(start,y-top,stop-start),
|
|
56
|
+
renderer.paintFor([70,150,220],95));
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|