1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2026-04-19 08:27:40 +00:00

Deploying to gh-pages from @ sehugg/8bitworkshop@fda7ae78a1 🚀

This commit is contained in:
sehugg
2026-03-02 17:48:57 +00:00
parent d1e812ed8a
commit f31ddf206d
20 changed files with 159 additions and 49 deletions
+2
View File
@@ -2,6 +2,8 @@ TSC=./node_modules/typescript/bin/tsc --build
LEZER=./node_modules/.bin/lezer-generator
TMP=./tmp/dist
all: buildtsc
# Ensure node_modules is up to date.
node_modules: package.json
npm install
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
import{a as x}from"./chunk-3FIVEUG2.js";import{t as y}from"./chunk-TLFCHGHO.js";import"./chunk-JSIZCY7X.js";import"./chunk-LNOKARBD.js";import"./chunk-2D2A225Y.js";import{I as m,m as c,p}from"./chunk-236FAHT6.js";import{$ as a,C as d,J as f,n as h}from"./chunk-QWAF5HSH.js";import"./chunk-KT7KMEQC.js";var n=31,s=class extends p{constructor(){super();this.cpuFrequency=1e6;this.defaultROMSize=32768;this.cpu=new c;this.ram=new Uint8Array(16384);this.read=a([[0,16383,16383,e=>this.ram[e]],[16384,16384,65535,e=>this.serial.byteAvailable()?128:0],[16385,16385,65535,e=>this.serial.recvByte()],[16386,16386,65535,e=>this.serial.clearToSend()?128:0],[32768,65535,32767,e=>this.rom&&this.rom[e]]]);this.write=a([[0,16383,16383,(e,r)=>{this.ram[e]=r}],[16387,16387,65535,(e,r)=>this.serial.sendByte(r)],[16399,16399,65535,(e,r)=>{this.inputs[n]=1}]]);this.connectCPUMemoryBus(this)}connectSerialIO(e){this.serial=e}readConst(e){return this.read(e)}advanceFrame(e){for(var r=0;r<this.cpuFrequency/60&&!(e&&e());)r+=this.advanceCPU();return r}advanceCPU(){if(this.isHalted())return 1;var e=super.advanceCPU();return this.serial&&this.serial.advance(e),e}reset(){this.inputs[n]=0,super.reset(),this.serial&&this.serial.reset()}isHalted(){return this.inputs[n]!=0}};var S=[{id:"hello.dasm",name:"Hello World (ASM)"}],l=class{constructor(t){t.style.overflowY="auto";var e=$('<div id="gameport"/>').appendTo(t);$('<p class="transcript-header">Serial Output</p>').appendTo(e);var r=$('<div id="windowport" class="transcript"/>').appendTo(e);this.div=r[0]}start(){this.tty=new x(this.div,!1)}reset(){this.tty.clear()}saveState(){return this.tty.saveState()}loadState(t){this.tty.loadState(t)}};function v(i){return i==10?"":i<32?String.fromCharCode(i+9216):String.fromCharCode(i)}var u=class{constructor(){this.bufferedRead=!0;this.cyclesPerByte=1e6/(57600/8);this.maxOutputBytes=4096}clearToSend(){return this.outputBytes.length<this.maxOutputBytes}sendByte(t){this.clearToSend()&&(this.outputBytes.push(t),this.viewer.tty.addtext(v(t),34),t==10&&this.viewer.tty.newline(),this.clearToSend()||(this.viewer.tty.newline(),this.viewer.tty.addtext("\u26A0\uFE0F OUTPUT BUFFER FULL \u26A0\uFE0F",4)))}byteAvailable(){return this.readIndex()>this.inputIndex}recvByte(){var t=this.readIndex();this.inputIndex=t;var e=(this.inputBytes&&this.inputBytes[t])|0;return this.viewer.tty.addtext(v(e),18),e==10&&this.viewer.tty.newline(),e}readIndex(){return this.bufferedRead?this.inputIndex+1:Math.floor(this.clk/this.cyclesPerByte)}reset(){this.inputIndex=-1,this.clk=0,this.outputBytes=[],this.bufin=""}advance(t){this.clk+=t}saveState(){return{clk:this.clk,idx:this.inputIndex,out:this.outputBytes.slice()}}loadState(t){this.clk=t.clk,this.inputIndex=t.idx,this.outputBytes=t.out.slice()}},o=class extends m{constructor(e){super(e);this.getMemoryMap=function(){return{main:[{name:"RAM",start:0,size:16384,type:"ram"},{name:"ROM",start:32768,size:32768,type:"rom"}]}};this.serview=new l(e)}async start(){super.start(),this.serial=new u,this.serial.viewer=this.serview,this.serview.start(),this.machine.connectSerialIO(this.serial)}reset(){this.serial.inputBytes=d(this.internalFiles["serialin.dat"]),super.reset(),this.serview.reset()}isBlocked(){return this.machine.isHalted()}advance(e){return this.isBlocked()?(this.internalFiles["serialout.dat"]=h(this.serial.outputBytes),y(),0):super.advance(e)}saveState(){var e=super.saveState();return e.serial=this.serial.saveState(),e.serview=this.serview.saveState(),e}loadState(e){super.loadState(e),this.serial.loadState(e.serial),this.serview.loadState(e.serview)}newMachine(){return new s}getPresets(){return S}getDefaultExtension(){return".dasm"}readAddress(e){return this.machine.readConst(e)}};f["devel-6502"]=o;export{u as SerialTestHarness};
//# sourceMappingURL=devel-LMKY26N2.js.map
import{a as x}from"./chunk-3FIVEUG2.js";import{t as y}from"./chunk-CUUCO5P6.js";import"./chunk-JSIZCY7X.js";import"./chunk-LNOKARBD.js";import"./chunk-ZAYXNXTS.js";import{I as m,m as c,p}from"./chunk-236FAHT6.js";import{$ as a,C as d,J as f,n as h}from"./chunk-QWAF5HSH.js";import"./chunk-KT7KMEQC.js";var n=31,s=class extends p{constructor(){super();this.cpuFrequency=1e6;this.defaultROMSize=32768;this.cpu=new c;this.ram=new Uint8Array(16384);this.read=a([[0,16383,16383,e=>this.ram[e]],[16384,16384,65535,e=>this.serial.byteAvailable()?128:0],[16385,16385,65535,e=>this.serial.recvByte()],[16386,16386,65535,e=>this.serial.clearToSend()?128:0],[32768,65535,32767,e=>this.rom&&this.rom[e]]]);this.write=a([[0,16383,16383,(e,r)=>{this.ram[e]=r}],[16387,16387,65535,(e,r)=>this.serial.sendByte(r)],[16399,16399,65535,(e,r)=>{this.inputs[n]=1}]]);this.connectCPUMemoryBus(this)}connectSerialIO(e){this.serial=e}readConst(e){return this.read(e)}advanceFrame(e){for(var r=0;r<this.cpuFrequency/60&&!(e&&e());)r+=this.advanceCPU();return r}advanceCPU(){if(this.isHalted())return 1;var e=super.advanceCPU();return this.serial&&this.serial.advance(e),e}reset(){this.inputs[n]=0,super.reset(),this.serial&&this.serial.reset()}isHalted(){return this.inputs[n]!=0}};var S=[{id:"hello.dasm",name:"Hello World (ASM)"}],l=class{constructor(t){t.style.overflowY="auto";var e=$('<div id="gameport"/>').appendTo(t);$('<p class="transcript-header">Serial Output</p>').appendTo(e);var r=$('<div id="windowport" class="transcript"/>').appendTo(e);this.div=r[0]}start(){this.tty=new x(this.div,!1)}reset(){this.tty.clear()}saveState(){return this.tty.saveState()}loadState(t){this.tty.loadState(t)}};function v(i){return i==10?"":i<32?String.fromCharCode(i+9216):String.fromCharCode(i)}var u=class{constructor(){this.bufferedRead=!0;this.cyclesPerByte=1e6/(57600/8);this.maxOutputBytes=4096}clearToSend(){return this.outputBytes.length<this.maxOutputBytes}sendByte(t){this.clearToSend()&&(this.outputBytes.push(t),this.viewer.tty.addtext(v(t),34),t==10&&this.viewer.tty.newline(),this.clearToSend()||(this.viewer.tty.newline(),this.viewer.tty.addtext("\u26A0\uFE0F OUTPUT BUFFER FULL \u26A0\uFE0F",4)))}byteAvailable(){return this.readIndex()>this.inputIndex}recvByte(){var t=this.readIndex();this.inputIndex=t;var e=(this.inputBytes&&this.inputBytes[t])|0;return this.viewer.tty.addtext(v(e),18),e==10&&this.viewer.tty.newline(),e}readIndex(){return this.bufferedRead?this.inputIndex+1:Math.floor(this.clk/this.cyclesPerByte)}reset(){this.inputIndex=-1,this.clk=0,this.outputBytes=[],this.bufin=""}advance(t){this.clk+=t}saveState(){return{clk:this.clk,idx:this.inputIndex,out:this.outputBytes.slice()}}loadState(t){this.clk=t.clk,this.inputIndex=t.idx,this.outputBytes=t.out.slice()}},o=class extends m{constructor(e){super(e);this.getMemoryMap=function(){return{main:[{name:"RAM",start:0,size:16384,type:"ram"},{name:"ROM",start:32768,size:32768,type:"rom"}]}};this.serview=new l(e)}async start(){super.start(),this.serial=new u,this.serial.viewer=this.serview,this.serview.start(),this.machine.connectSerialIO(this.serial)}reset(){this.serial.inputBytes=d(this.internalFiles["serialin.dat"]),super.reset(),this.serview.reset()}isBlocked(){return this.machine.isHalted()}advance(e){return this.isBlocked()?(this.internalFiles["serialout.dat"]=h(this.serial.outputBytes),y(),0):super.advance(e)}saveState(){var e=super.saveState();return e.serial=this.serial.saveState(),e.serview=this.serview.saveState(),e}loadState(e){super.loadState(e),this.serial.loadState(e.serial),this.serview.loadState(e.serview)}newMachine(){return new s}getPresets(){return S}getDefaultExtension(){return".dasm"}readAddress(e){return this.machine.readConst(e)}};f["devel-6502"]=o;export{u as SerialTestHarness};
//# sourceMappingURL=devel-7Z2P4DPN.js.map
+1 -1
View File
@@ -1,2 +1,2 @@
import{b as v,c as P}from"./chunk-2D2A225Y.js";import{A as p,E as w,J as c,l as u,m,y as g}from"./chunk-QWAF5HSH.js";import{e as I}from"./chunk-KT7KMEQC.js";var k=I(P()),i,a,l,h=(function(e){if(!e||e.length==0)return{};for(var r={},t=0;t<e.length;++t){var o=e[t].split("=",2);o.length==1?r[o[0]]="":r[o[0]]=decodeURIComponent(o[1].replace(/\+/g," "))}return r})(window.location.search.substr(1).split("&"));function x(){typeof window.onerror=="object"&&(window.onerror=function(e,r,t,o,n){var s=e+" "+r+" "+t+":"+o+", "+n;$.get("/error?msg="+encodeURIComponent(s),"text")})}function M(){var e=!1;document.addEventListener("visibilitychange",function(r){document.visibilityState=="hidden"&&a.isRunning()?(a.pause(),e=!0):document.visibilityState=="visible"&&e&&(a.resume(),e=!1)}),$(window).on("focus",function(){e&&(a.resume(),e=!1)}),$(window).on("blur",function(){a.isRunning()&&(a.pause(),e=!0)})}async function y(e,r){if(!r){alert("No ROM found.");return}console.log(r.length+" bytes"),await a.loadROM(e,r),a.resume()}function R(){return $("#emulator").find("canvas")}function E(e,r,t){w("gif.js/dist/gif.js").then(()=>{var o=R()[0];if(!o){alert("Could not find canvas element to record video!");return}var n=0;o.style&&o.style.transform&&(o.style.transform.indexOf("rotate(-90deg)")>=0?n=-1:o.style.transform.indexOf("rotate(90deg)")>=0&&(n=1));var s=new GIF({workerScript:"gif.js/dist/gif.worker.js",workers:4,quality:10,rotate:n});s.on("finished",function(C){console.log("finished encoding GIF"),t(C)}),e=e||100+(Math.random()*256&3),r=r||100+(Math.random()*256&15);var f=0;console.log("Recording video",o);var d=()=>{f++>r?(console.log("Rendering video"),s.render()):(s.addFrame(o,{delay:e,copy:!0}),setTimeout(d,e))};d()})}async function S(e){if(!c[i])throw Error("Invalid platform '"+i+"'.");a=new c[i]($("#emuscreen")[0]),await a.start(),e.rec&&R().on("focus",()=>{a.resume()});var r=e.n||"Game",t,o=e.url,n=e.r;if(o)return console.log(o),g(o,f=>{y(r,f)},"arraybuffer"),!0;if(n){var s=m(atob(n));t=new u().decode(s)}return M(),y(r,t),!0}async function b(e){if(e.data&&(e=e.data),i=e.p,!i)throw new Error("No platform variable!");try{var r=await v(p(i));console.log("starting platform",i),await S(e)}catch(t){console.log(t),alert('Platform "'+i+'" not supported.')}}function F(){x(),h.p&&b(h)}window.addEventListener("message",O,!1);function O(e){if(e.data){var r=e.data.cmd;if(r=="start"&&!a)b(e);else if(r=="reset")a.reset(),l.reset();else if(r=="getReplay"){var t={frameCount:l.frameCount,checkpoints:l.checkpoints,framerecs:l.framerecs,checkpointInterval:l.checkpointInterval,maxCheckpoints:l.maxCheckpoints};e.source.postMessage({ack:r,replay:t},e.origin)}else if(r=="watchState"){var o=new Function("platform","state",e.data.fn);l.callbackNewCheckpoint=n=>{e.source.postMessage({ack:r,state:o(a,n)},e.origin)}}else r=="recordVideo"?E(e.data.intervalMsec,e.data.maxFrames,function(n){e.data.filename&&(0,k.saveAs)(n,e.data.filename),e.source.postMessage({ack:r,gif:n},e.origin)}):console.log("Unknown data.cmd: "+r)}}self===top&&(document.body.style.backgroundColor="#555");F();export{a as platform,i as platform_id,F as startEmbed,l as stateRecorder};
import{b as v,c as P}from"./chunk-ZAYXNXTS.js";import{A as p,E as w,J as c,l as u,m,y as g}from"./chunk-QWAF5HSH.js";import{e as I}from"./chunk-KT7KMEQC.js";var k=I(P()),i,a,l,h=(function(e){if(!e||e.length==0)return{};for(var r={},t=0;t<e.length;++t){var o=e[t].split("=",2);o.length==1?r[o[0]]="":r[o[0]]=decodeURIComponent(o[1].replace(/\+/g," "))}return r})(window.location.search.substr(1).split("&"));function x(){typeof window.onerror=="object"&&(window.onerror=function(e,r,t,o,n){var s=e+" "+r+" "+t+":"+o+", "+n;$.get("/error?msg="+encodeURIComponent(s),"text")})}function M(){var e=!1;document.addEventListener("visibilitychange",function(r){document.visibilityState=="hidden"&&a.isRunning()?(a.pause(),e=!0):document.visibilityState=="visible"&&e&&(a.resume(),e=!1)}),$(window).on("focus",function(){e&&(a.resume(),e=!1)}),$(window).on("blur",function(){a.isRunning()&&(a.pause(),e=!0)})}async function y(e,r){if(!r){alert("No ROM found.");return}console.log(r.length+" bytes"),await a.loadROM(e,r),a.resume()}function R(){return $("#emulator").find("canvas")}function E(e,r,t){w("gif.js/dist/gif.js").then(()=>{var o=R()[0];if(!o){alert("Could not find canvas element to record video!");return}var n=0;o.style&&o.style.transform&&(o.style.transform.indexOf("rotate(-90deg)")>=0?n=-1:o.style.transform.indexOf("rotate(90deg)")>=0&&(n=1));var s=new GIF({workerScript:"gif.js/dist/gif.worker.js",workers:4,quality:10,rotate:n});s.on("finished",function(C){console.log("finished encoding GIF"),t(C)}),e=e||100+(Math.random()*256&3),r=r||100+(Math.random()*256&15);var f=0;console.log("Recording video",o);var d=()=>{f++>r?(console.log("Rendering video"),s.render()):(s.addFrame(o,{delay:e,copy:!0}),setTimeout(d,e))};d()})}async function S(e){if(!c[i])throw Error("Invalid platform '"+i+"'.");a=new c[i]($("#emuscreen")[0]),await a.start(),e.rec&&R().on("focus",()=>{a.resume()});var r=e.n||"Game",t,o=e.url,n=e.r;if(o)return console.log(o),g(o,f=>{y(r,f)},"arraybuffer"),!0;if(n){var s=m(atob(n));t=new u().decode(s)}return M(),y(r,t),!0}async function b(e){if(e.data&&(e=e.data),i=e.p,!i)throw new Error("No platform variable!");try{var r=await v(p(i));console.log("starting platform",i),await S(e)}catch(t){console.log(t),alert('Platform "'+i+'" not supported.')}}function F(){x(),h.p&&b(h)}window.addEventListener("message",O,!1);function O(e){if(e.data){var r=e.data.cmd;if(r=="start"&&!a)b(e);else if(r=="reset")a.reset(),l.reset();else if(r=="getReplay"){var t={frameCount:l.frameCount,checkpoints:l.checkpoints,framerecs:l.framerecs,checkpointInterval:l.checkpointInterval,maxCheckpoints:l.maxCheckpoints};e.source.postMessage({ack:r,replay:t},e.origin)}else if(r=="watchState"){var o=new Function("platform","state",e.data.fn);l.callbackNewCheckpoint=n=>{e.source.postMessage({ack:r,state:o(a,n)},e.origin)}}else r=="recordVideo"?E(e.data.intervalMsec,e.data.maxFrames,function(n){e.data.filename&&(0,k.saveAs)(n,e.data.filename),e.source.postMessage({ack:r,gif:n},e.origin)}):console.log("Unknown data.cmd: "+r)}}self===top&&(document.body.style.backgroundColor="#555");F();export{a as platform,i as platform_id,F as startEmbed,l as stateRecorder};
//# sourceMappingURL=embedui.js.map
+8
View File
@@ -200,6 +200,7 @@ class SourceEditor {
}),
gutter_1.errorMarkers.field,
visuals_1.errorMessages.field,
visuals_1.errorSpans.field,
gutter_1.currentPcMarker.field,
gutter_1.currentPcMarker.gutter,
visuals_1.highlightLines.field,
@@ -279,6 +280,7 @@ class SourceEditor {
this.clearErrors();
errors = errors.slice(0, MAX_ERRORS);
const newErrors = new Map();
const spans = [];
for (var info of errors) {
// only mark errors with this filename, or without any filename
if (!info.path || this.path.endsWith(info.path)) {
@@ -287,11 +289,16 @@ class SourceEditor {
if (isNaN(line) || line < 1 || line > numLines)
line = 1;
newErrors.set(line, info.msg);
// collect column-level spans
if (info.start != null && info.end != null && info.end > info.start) {
spans.push({ line, start: info.start, end: info.end });
}
}
}
this.editor.dispatch({
effects: [
gutter_1.errorMarkers.set.of(newErrors),
visuals_1.errorSpans.effect.of(spans.length > 0 ? spans : null),
],
});
}
@@ -301,6 +308,7 @@ class SourceEditor {
effects: [
gutter_1.errorMarkers.set.of(new Map()),
gutter_1.errorMarkers.showMessage.of(null),
visuals_1.errorSpans.effect.of(null),
],
});
}
File diff suppressed because one or more lines are too long
+40 -1
View File
@@ -1,6 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.highlightLines = exports.showValue = exports.currentPc = exports.errorMessages = void 0;
exports.highlightLines = exports.errorSpans = exports.showValue = exports.currentPc = exports.errorMessages = void 0;
const gutter_1 = require("./gutter");
const state_1 = require("@codemirror/state");
const view_1 = require("@codemirror/view");
@@ -147,6 +147,41 @@ const showValueDecorationField = state_1.StateField.define({
},
provide: f => view_1.EditorView.decorations.from(f),
});
// Error span decorations for inline column-range highlighting
const errorSpansEffect = state_1.StateEffect.define();
const errorSpanDecoration = view_1.Decoration.mark({
attributes: { class: "cm-error-span" }
});
const errorSpansField = state_1.StateField.define({
create() { return view_1.Decoration.none; },
update(decorations, tr) {
decorations = decorations.map(tr.changes);
for (let e of tr.effects) {
if (e.is(errorSpansEffect)) {
if (e.value === null)
return view_1.Decoration.none;
const ranges = [];
for (const span of e.value) {
try {
const line = tr.state.doc.line(span.line);
const from = line.from + span.start;
const to = line.from + span.end;
// Clamp to line boundaries
if (from >= line.from && to <= line.to && from < to) {
ranges.push(errorSpanDecoration.range(from, to));
}
}
catch (_a) {
// Line doesn't exist, skip
}
}
return view_1.Decoration.set(ranges, true);
}
}
return decorations;
},
provide: f => view_1.EditorView.decorations.from(f),
});
const highlightLinesEffect = state_1.StateEffect.define();
const highlightLinesDecoration = view_1.Decoration.line({
attributes: { class: "highlight-lines" }
@@ -191,6 +226,10 @@ exports.showValue = {
effect: showValueEffect,
field: showValueDecorationField,
};
exports.errorSpans = {
effect: errorSpansEffect,
field: errorSpansField,
};
exports.highlightLines = {
effect: highlightLinesEffect,
field: highlightLinesField,
File diff suppressed because one or more lines are too long
+4
View File
@@ -18,6 +18,10 @@ exports.editorTheme = view_1.EditorView.theme({
".highlight-lines": {
backgroundColor: "#003399 !important",
},
".cm-error-span": {
textDecoration: "underline wavy red",
backgroundColor: "rgba(255, 0, 0, 0.15)",
},
".gutter-offset": {
marginRight: "0.25em",
},
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"editorTheme.js","sourceRoot":"","sources":["../../src/themes/editorTheme.ts"],"names":[],"mappings":";;;AAAA,2CAA8C;AAEjC,QAAA,WAAW,GAAG,iBAAU,CAAC,KAAK,CAAC;IACxC,GAAG,EAAE;QACD,MAAM,EAAE,MAAM;KACjB;IACD,eAAe,EAAE;QACb,eAAe,EAAE,oBAAoB;KACxC;IACD,yBAAyB,EAAE;QACvB,eAAe,EAAE,oBAAoB;KACxC;IACD,2BAA2B,EAAE;QACzB,KAAK,EAAE,SAAS;KACnB;IACD,kBAAkB,EAAE;QAChB,eAAe,EAAE,oBAAoB;KACxC;IACD,gBAAgB,EAAE;QACd,WAAW,EAAE,QAAQ;KACxB;IACD,eAAe,EAAE;QACb,UAAU,EAAE,QAAQ;QACpB,WAAW,EAAE,QAAQ;QACrB,OAAO,EAAE,GAAG;KACf;IACD,mBAAmB,EAAE;QACjB,KAAK,EAAE,SAAS;KACnB;IACD,eAAe,EAAE;QACb,UAAU,EAAE,QAAQ;QACpB,WAAW,EAAE,QAAQ;KACxB;IACD,qCAAqC,EAAE;QACnC,KAAK,EAAE,SAAS;KACnB;CACJ,CAAC,CAAC"}
{"version":3,"file":"editorTheme.js","sourceRoot":"","sources":["../../src/themes/editorTheme.ts"],"names":[],"mappings":";;;AAAA,2CAA8C;AAEjC,QAAA,WAAW,GAAG,iBAAU,CAAC,KAAK,CAAC;IACxC,GAAG,EAAE;QACD,MAAM,EAAE,MAAM;KACjB;IACD,eAAe,EAAE;QACb,eAAe,EAAE,oBAAoB;KACxC;IACD,yBAAyB,EAAE;QACvB,eAAe,EAAE,oBAAoB;KACxC;IACD,2BAA2B,EAAE;QACzB,KAAK,EAAE,SAAS;KACnB;IACD,kBAAkB,EAAE;QAChB,eAAe,EAAE,oBAAoB;KACxC;IACD,gBAAgB,EAAE;QACd,cAAc,EAAE,oBAAoB;QACpC,eAAe,EAAE,uBAAuB;KAC3C;IACD,gBAAgB,EAAE;QACd,WAAW,EAAE,QAAQ;KACxB;IACD,eAAe,EAAE;QACb,UAAU,EAAE,QAAQ;QACpB,WAAW,EAAE,QAAQ;QACrB,OAAO,EAAE,GAAG;KACf;IACD,mBAAmB,EAAE;QACjB,KAAK,EAAE,SAAS;KACnB;IACD,eAAe,EAAE;QACb,UAAU,EAAE,QAAQ;QACpB,WAAW,EAAE,QAAQ;KACxB;IACD,qCAAqC,EAAE;QACnC,KAAK,EAAE,SAAS;KACnB;CACJ,CAAC,CAAC"}
+1 -1
View File
@@ -1,2 +1,2 @@
import{A as z,B as A,C as B,D as C,b as a,c as b,d as c,e as d,f as e,g as f,h as g,i as h,j as i,k as j,l as k,m as l,n as m,o as n,p as o,q as p,r as q,s as r,t as s,u as t,v as u,w as v,x as w,y as x,z as y}from"./chunk-TLFCHGHO.js";import"./chunk-JSIZCY7X.js";import"./chunk-LNOKARBD.js";import"./chunk-2D2A225Y.js";import"./chunk-236FAHT6.js";import"./chunk-QWAF5HSH.js";import"./chunk-KT7KMEQC.js";export{q as clearBreakpoint,f as current_project,A as emulationHalted,n as getCurrentEditorFilename,m as getCurrentMainFilename,k as getCurrentOutput,j as getCurrentProject,v as getPlatformAndRepo,i as getPlatformStore,z as getSaveState,y as getTestOutput,l as getWorkerParams,t as gotoNewLocation,s as haltEmulation,C as highlightSearch,h as lastDebugState,e as platform,b as platform_id,g as projectWindows,a as qs,B as reloadWorkspaceFile,d as repo_id,p as runToPC,r as setFrameRateUI,x as setTestInput,o as setupBreakpoint,u as setupSplits,w as startUI,c as store_id};
import{A as z,B as A,C as B,D as C,b as a,c as b,d as c,e as d,f as e,g as f,h as g,i as h,j as i,k as j,l as k,m as l,n as m,o as n,p as o,q as p,r as q,s as r,t as s,u as t,v as u,w as v,x as w,y as x,z as y}from"./chunk-CUUCO5P6.js";import"./chunk-JSIZCY7X.js";import"./chunk-LNOKARBD.js";import"./chunk-ZAYXNXTS.js";import"./chunk-236FAHT6.js";import"./chunk-QWAF5HSH.js";import"./chunk-KT7KMEQC.js";export{q as clearBreakpoint,f as current_project,A as emulationHalted,n as getCurrentEditorFilename,m as getCurrentMainFilename,k as getCurrentOutput,j as getCurrentProject,v as getPlatformAndRepo,i as getPlatformStore,z as getSaveState,y as getTestOutput,l as getWorkerParams,t as gotoNewLocation,s as haltEmulation,C as highlightSearch,h as lastDebugState,e as platform,b as platform_id,g as projectWindows,a as qs,B as reloadWorkspaceFile,d as repo_id,p as runToPC,r as setFrameRateUI,x as setTestInput,o as setupBreakpoint,u as setupSplits,w as startUI,c as store_id};
//# sourceMappingURL=ui.js.map
+10 -1
View File
@@ -27,7 +27,7 @@ import { debugHighlightTagsTooltip } from "./debug";
import { createTextTransformFilterEffect, textTransformFilterCompartment } from "./filters";
import { breakpointMarkers, bytes, clock, currentPcMarker, errorMarkers, offset, statusMarkers } from "./gutter";
import { tabKeymap } from "./tabs";
import { currentPc, errorMessages, highlightLines, showValue } from "./visuals";
import { currentPc, errorMessages, errorSpans, highlightLines, showValue } from "./visuals";
// TODO: make this an easily toggleable debug setting.
// Debug syntax highlighting. Useful when developing new parsers and themes.
@@ -237,6 +237,8 @@ export class SourceEditor implements ProjectView {
errorMessages.field,
errorSpans.field,
currentPcMarker.field,
currentPcMarker.gutter,
@@ -329,6 +331,7 @@ export class SourceEditor implements ProjectView {
this.clearErrors();
errors = errors.slice(0, MAX_ERRORS);
const newErrors = new Map<number, string>();
const spans: { line: number, start: number, end: number }[] = [];
for (var info of errors) {
// only mark errors with this filename, or without any filename
if (!info.path || this.path.endsWith(info.path)) {
@@ -336,11 +339,16 @@ export class SourceEditor implements ProjectView {
var line = info.line;
if (isNaN(line) || line < 1 || line > numLines) line = 1;
newErrors.set(line, info.msg);
// collect column-level spans
if (info.start != null && info.end != null && info.end > info.start) {
spans.push({ line, start: info.start, end: info.end });
}
}
}
this.editor.dispatch({
effects: [
errorMarkers.set.of(newErrors),
errorSpans.effect.of(spans.length > 0 ? spans : null),
],
});
}
@@ -351,6 +359,7 @@ export class SourceEditor implements ProjectView {
effects: [
errorMarkers.set.of(new Map()),
errorMarkers.showMessage.of(null),
errorSpans.effect.of(null),
],
});
}
+44
View File
@@ -158,6 +158,45 @@ const showValueDecorationField = StateField.define({
provide: f => EditorView.decorations.from(f),
});
// Error span decorations for inline column-range highlighting
const errorSpansEffect = StateEffect.define<{ line: number, start: number, end: number }[] | null>();
const errorSpanDecoration = Decoration.mark({
attributes: { class: "cm-error-span" }
});
const errorSpansField = StateField.define({
create() { return Decoration.none },
update(decorations, tr) {
decorations = decorations.map(tr.changes);
for (let e of tr.effects) {
if (e.is(errorSpansEffect)) {
if (e.value === null) return Decoration.none;
const ranges: any[] = [];
for (const span of e.value) {
try {
const line = tr.state.doc.line(span.line);
const from = line.from + span.start;
const to = line.from + span.end;
// Clamp to line boundaries
if (from >= line.from && to <= line.to && from < to) {
ranges.push(errorSpanDecoration.range(from, to));
}
} catch {
// Line doesn't exist, skip
}
}
return Decoration.set(ranges, true);
}
}
return decorations;
},
provide: f => EditorView.decorations.from(f),
});
const highlightLinesEffect = StateEffect.define<{ start: number, end: number } | null>();
const highlightLinesDecoration = Decoration.line({
@@ -210,6 +249,11 @@ export const showValue = {
field: showValueDecorationField,
};
export const errorSpans = {
effect: errorSpansEffect,
field: errorSpansField,
};
export const highlightLines = {
effect: highlightLinesEffect,
field: highlightLinesField,
+4
View File
@@ -16,6 +16,10 @@ export const editorTheme = EditorView.theme({
".highlight-lines": {
backgroundColor: "#003399 !important",
},
".cm-error-span": {
textDecoration: "underline wavy red",
backgroundColor: "rgba(255, 0, 0, 0.15)",
},
".gutter-offset": {
marginRight: "0.25em",
},