Shortcuts for reset and run
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
pub mod display;
|
pub mod display;
|
||||||
|
mod keyboard;
|
||||||
|
|
||||||
|
|||||||
Generated
+23
-6
@@ -7,6 +7,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/commands": "^6.5.0",
|
"@codemirror/commands": "^6.5.0",
|
||||||
"@codemirror/language": "^6.10.1",
|
"@codemirror/language": "^6.10.1",
|
||||||
|
"@codemirror/state": "^6.5.2",
|
||||||
"@codemirror/view": "^6.26.3",
|
"@codemirror/view": "^6.26.3",
|
||||||
"cm6-theme-gruvbox-dark": "^0.2.0",
|
"cm6-theme-gruvbox-dark": "^0.2.0",
|
||||||
"codemirror": "^6.0.1",
|
"codemirror": "^6.0.1",
|
||||||
@@ -79,9 +80,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/state": {
|
"node_modules/@codemirror/state": {
|
||||||
"version": "6.4.1",
|
"version": "6.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz",
|
||||||
"integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A=="
|
"integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@marijn/find-cluster-break": "^1.0.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@codemirror/view": {
|
"node_modules/@codemirror/view": {
|
||||||
"version": "6.26.3",
|
"version": "6.26.3",
|
||||||
@@ -444,6 +448,11 @@
|
|||||||
"@lezer/common": "^1.0.0"
|
"@lezer/common": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@marijn/find-cluster-break": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g=="
|
||||||
|
},
|
||||||
"node_modules/ansi-regex": {
|
"node_modules/ansi-regex": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
@@ -686,9 +695,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@codemirror/state": {
|
"@codemirror/state": {
|
||||||
"version": "6.4.1",
|
"version": "6.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz",
|
||||||
"integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A=="
|
"integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==",
|
||||||
|
"requires": {
|
||||||
|
"@marijn/find-cluster-break": "^1.0.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"@codemirror/view": {
|
"@codemirror/view": {
|
||||||
"version": "6.26.3",
|
"version": "6.26.3",
|
||||||
@@ -853,6 +865,11 @@
|
|||||||
"@lezer/common": "^1.0.0"
|
"@lezer/common": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@marijn/find-cluster-break": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g=="
|
||||||
|
},
|
||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/commands": "^6.5.0",
|
"@codemirror/commands": "^6.5.0",
|
||||||
"@codemirror/language": "^6.10.1",
|
"@codemirror/language": "^6.10.1",
|
||||||
|
"@codemirror/state": "^6.5.2",
|
||||||
"@codemirror/view": "^6.26.3",
|
"@codemirror/view": "^6.26.3",
|
||||||
"cm6-theme-gruvbox-dark": "^0.2.0",
|
"cm6-theme-gruvbox-dark": "^0.2.0",
|
||||||
"codemirror": "^6.0.1",
|
"codemirror": "^6.0.1",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {indentWithTab} from '@codemirror/commands'
|
|||||||
import {StreamLanguage} from '@codemirror/language'
|
import {StreamLanguage} from '@codemirror/language'
|
||||||
import {gruvboxDark} from 'cm6-theme-gruvbox-dark'
|
import {gruvboxDark} from 'cm6-theme-gruvbox-dark'
|
||||||
import ForgeHighlighter from './forge_highlighter'
|
import ForgeHighlighter from './forge_highlighter'
|
||||||
|
import { Prec } from "@codemirror/state"
|
||||||
|
|
||||||
export default function ForgeEditor({ src, updateSrc, fileName }) {
|
export default function ForgeEditor({ src, updateSrc, fileName }) {
|
||||||
const editor = useRef(null)
|
const editor = useRef(null)
|
||||||
@@ -16,6 +17,12 @@ export default function ForgeEditor({ src, updateSrc, fileName }) {
|
|||||||
doc: src,
|
doc: src,
|
||||||
extensions: [
|
extensions: [
|
||||||
basicSetup,
|
basicSetup,
|
||||||
|
// Normally F3 opens the search dialog, but we want to just eat it so the document's handler will get it.
|
||||||
|
// We use F3 as a global shortcut for resetting the machine, even if the editor has focus.
|
||||||
|
// Since the editor doesn't do anything for F1, 2, or 4, we don't need to do anything to ignore those.
|
||||||
|
Prec.highest(
|
||||||
|
keymap.of([{ key: "F3", run: () => { return true } }])
|
||||||
|
),
|
||||||
keymap.of([indentWithTab]),
|
keymap.of([indentWithTab]),
|
||||||
gruvboxDark,
|
gruvboxDark,
|
||||||
EditorView.updateListener.of((update) => {
|
EditorView.updateListener.of((update) => {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export default function({ src: defaultSrc }) {
|
|||||||
const [errors, setErrors] = useState(null) // What's displayed on the compile errors tab
|
const [errors, setErrors] = useState(null) // What's displayed on the compile errors tab
|
||||||
const [status, setStatus] = useState('') // The contents of the status bar
|
const [status, setStatus] = useState('') // The contents of the status bar
|
||||||
const [stale, setStale] = useState(false) // Whether the editor has been changed since the last build
|
const [stale, setStale] = useState(false) // Whether the editor has been changed since the last build
|
||||||
|
const [keyFocus, setKeyFocus] = useState('editor') // The lens for interpreting key events: 'editor', 'emulator', 'filelist'
|
||||||
// Whether the emulator should be running. Has to be a ref because the CPU setTimeout loop won't ever see changes in it otherwise
|
// Whether the emulator should be running. Has to be a ref because the CPU setTimeout loop won't ever see changes in it otherwise
|
||||||
const running = useRef(false)
|
const running = useRef(false)
|
||||||
|
|
||||||
@@ -131,6 +132,24 @@ export default function({ src: defaultSrc }) {
|
|||||||
content = <ForgeEditor build={build} run={run} updateSrc={updateSrc} src={src} fileName={currentFile}/>
|
content = <ForgeEditor build={build} run={run} updateSrc={updateSrc} src={src} fileName={currentFile}/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const listener = (event) => {
|
||||||
|
// F1-4 act the same in every mode:
|
||||||
|
if (event.key === 'F3') {
|
||||||
|
event.preventDefault()
|
||||||
|
reset()
|
||||||
|
}
|
||||||
|
if (event.key === 'F4') {
|
||||||
|
event.preventDefault()
|
||||||
|
setKeyFocus('emulator')
|
||||||
|
run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener('keydown', listener)
|
||||||
|
|
||||||
|
return () => document.removeEventListener('keydown', listener)
|
||||||
|
}, [reset, run])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Tabbar activeTab={activeTab} setActiveTab={setActiveTab} anyErrors={!!errors}/>
|
<Tabbar activeTab={activeTab} setActiveTab={setActiveTab} anyErrors={!!errors}/>
|
||||||
@@ -168,7 +187,7 @@ function Tabbar({ activeTab, setActiveTab, anyErrors }) {
|
|||||||
const classNames = name => (name === activeTab ? 'button active' : 'button')
|
const classNames = name => (name === activeTab ? 'button active' : 'button')
|
||||||
return (
|
return (
|
||||||
<div className='tabbar'>
|
<div className='tabbar'>
|
||||||
<a className={classNames('editor')} onClick={onChangeTab} data-tab='editor'>[Editor]</a>
|
<a className={classNames('editor')} onClick={onChangeTab} data-tab='editor'>[Editor (F2)]</a>
|
||||||
<a className={classNames('assembly')} onClick={onChangeTab} data-tab='assembly'>[Assembly]</a>
|
<a className={classNames('assembly')} onClick={onChangeTab} data-tab='assembly'>[Assembly]</a>
|
||||||
{anyErrors && <a className={classNames('errors')} onClick={onChangeTab} data-tab='errors'>[Errors]</a>}
|
{anyErrors && <a className={classNames('errors')} onClick={onChangeTab} data-tab='errors'>[Errors]</a>}
|
||||||
</div>
|
</div>
|
||||||
@@ -176,25 +195,26 @@ function Tabbar({ activeTab, setActiveTab, anyErrors }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Toolbar of the controls for the simulator
|
// Toolbar of the controls for the simulator
|
||||||
function Toolbar({activeTab, running, compile, build, run, stop, reset, addFile, removeFile }) {
|
function Toolbar({ running, build, run, stop, reset, addFile, removeFile }) {
|
||||||
let buildBtn, runBtn
|
let buildBtn, runBtn
|
||||||
// TODO: Make this assemble on assembly tab, make that editable
|
// TODO: Make this assemble on assembly tab, make that editable
|
||||||
buildBtn = <a className='build' onClick={build}>[Build]</a>
|
buildBtn = <a className='build' onClick={build}>[Build]</a>
|
||||||
|
|
||||||
if (running) {
|
if (running) {
|
||||||
runBtn = <a className='stop' onClick={stop}>[Stop]</a>
|
runBtn = <a className='stop' onClick={stop}>[Stop (F4)]</a>
|
||||||
} else {
|
} else {
|
||||||
runBtn = <a className='run' onClick={run}>[Run]</a>
|
runBtn = <a className='run' onClick={run}>[Run (F4)]</a>
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='file-buttons'>
|
<div className='file-buttons'>
|
||||||
|
(F1)
|
||||||
<a className='new' onClick={addFile}>[new]</a>
|
<a className='new' onClick={addFile}>[new]</a>
|
||||||
<a className='del' onClick={removeFile}>[del]</a>
|
<a className='del' onClick={removeFile}>[del]</a>
|
||||||
</div>
|
</div>
|
||||||
<div className='buttons'>
|
<div className='buttons'>
|
||||||
<a className='reset' onClick={reset}>[Reset]</a>
|
<a className='reset' onClick={reset}>[Reset (F3)]</a>
|
||||||
{buildBtn}
|
{buildBtn}
|
||||||
{runBtn}
|
{runBtn}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user