some more autocomplete magic

This commit is contained in:
Luck
2021-05-20 16:17:54 +01:00
parent 2e99fa9dab
commit 148c5b6f28

View File

@@ -1,4 +1,4 @@
import { useRef } from 'react'; import { useState, useRef } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import ReactEditor from 'react-simple-code-editor'; import ReactEditor from 'react-simple-code-editor';
import EditorPrismStyle from './EditorPrismStyle'; import EditorPrismStyle from './EditorPrismStyle';
@@ -14,9 +14,10 @@ export default function EditorTextArea({ code, setCode, language, fontSize }) {
.join('\n'); .join('\n');
} }
const lastBracketState = useState(null);
const editorRef = useRef(); const editorRef = useRef();
function keydown(e) { function keydown(e) {
handleKeydown(e, editorRef.current); handleKeydown(e, editorRef.current, lastBracketState);
} }
return ( return (
@@ -65,40 +66,71 @@ const StyledReactEditor = styled(ReactEditor)`
const KEYCODE_ENTER = 13; const KEYCODE_ENTER = 13;
const KEYCODE_PARENS = 57; const KEYCODE_PARENS = 57;
const KEYCODE_PARENS_CLOSE = 48;
const KEYCODE_BRACKETS = 219; const KEYCODE_BRACKETS = 219;
const KEYCODE_BRACKETS_CLOSE = 221;
const KEYCODE_QUOTE = 222; const KEYCODE_QUOTE = 222;
const KEYCODE_BACK_QUOTE = 192; const KEYCODE_BACK_QUOTE = 192;
function getPair(e) { function getPair({ keyCode, shiftKey }) {
if (e.keyCode === KEYCODE_PARENS && e.shiftKey) { if (keyCode === KEYCODE_PARENS && shiftKey) {
return ['(', ')']; return ['(', ')'];
} else if (e.keyCode === KEYCODE_BRACKETS) { } else if (keyCode === KEYCODE_BRACKETS) {
if (e.shiftKey) { if (shiftKey) {
return ['{', '}']; return ['{', '}'];
} else { } else {
return ['[', ']']; return ['[', ']'];
} }
} else if (e.keyCode === KEYCODE_QUOTE) { } else if (keyCode === KEYCODE_QUOTE) {
if (e.shiftKey) { if (shiftKey) {
return ['"', '"']; return ['"', '"'];
} else { } else {
return ["'", "'"]; return ["'", "'"];
} }
} else if (e.keyCode === KEYCODE_BACK_QUOTE && !e.shiftKey) { } else if (keyCode === KEYCODE_BACK_QUOTE && !shiftKey) {
return ['`', '`']; return ['`', '`'];
} }
return null; return null;
} }
function handleKeydown(e, editor) { function handleKeydown(e, editor, [autoBracket, setAutoBracket]) {
const { value, selectionStart, selectionEnd } = e.target; const { value, selectionStart, selectionEnd } = e.target;
if (selectionStart !== selectionEnd) { if (selectionStart !== selectionEnd) {
return; return;
} }
// If the user types a closing bracket explictly, just jump to after the automatically added one
if (
selectionStart !== 0 &&
autoBracket === e.key &&
(e.keyCode === KEYCODE_BRACKETS_CLOSE || e.keyCode === KEYCODE_PARENS_CLOSE)
) {
e.preventDefault();
editor._applyEdits({
value: value,
selectionStart: selectionStart + 1,
selectionEnd: selectionStart + 1,
});
setAutoBracket(null);
return;
}
// reset auto brackets
setAutoBracket(null);
// When entering an open bracket/quote, add the closing one // When entering an open bracket/quote, add the closing one
const pair = getPair(e); const pair = getPair(e);
if (pair) { if (pair) {
// don't add double apostrophes if it looks like a sentence
if (
e.keyCode === KEYCODE_QUOTE &&
!e.shiftKey &&
selectionStart !== 0 &&
/[a-zA-Z]/.test(value.charAt(selectionStart - 1))
) {
return;
}
e.preventDefault(); e.preventDefault();
editor._applyEdits({ editor._applyEdits({
value: value:
@@ -109,6 +141,7 @@ function handleKeydown(e, editor) {
selectionStart: selectionStart + 1, selectionStart: selectionStart + 1,
selectionEnd: selectionStart + 1, selectionEnd: selectionStart + 1,
}); });
setAutoBracket(pair[1]);
} }
// When pressing enter immediately after an open bracket, automatically add a newline plus extra indent // When pressing enter immediately after an open bracket, automatically add a newline plus extra indent