mirror of
https://github.com/hazemKrimi/touch-programming.git
synced 2026-05-01 18:20:26 +00:00
Add cursor and format code properly
This commit is contained in:
+1
-1
@@ -8,7 +8,7 @@
|
||||
"build": "vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview",
|
||||
"format": "prettier -w src"
|
||||
"format": "prettier -w src"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^18.3.1",
|
||||
|
||||
+13
-18
@@ -1,7 +1,7 @@
|
||||
.container {
|
||||
margin: auto;
|
||||
padding: 1rem;
|
||||
letter-spacing: 0.25rem;
|
||||
letter-spacing: 0.12rem;
|
||||
}
|
||||
|
||||
.pending {
|
||||
@@ -9,7 +9,8 @@
|
||||
}
|
||||
|
||||
.highlight {
|
||||
color: white;
|
||||
color: gray;
|
||||
animation: blink 0.75s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.correct {
|
||||
@@ -20,22 +21,16 @@
|
||||
color: red;
|
||||
}
|
||||
|
||||
.enter:before {
|
||||
content: '\21b5';
|
||||
display: inline-block;
|
||||
}
|
||||
@keyframes blink {
|
||||
0% {
|
||||
border-left: 1px solid white;
|
||||
}
|
||||
|
||||
.enter:after {
|
||||
content: '';
|
||||
display: block;
|
||||
clear: right;
|
||||
}
|
||||
50% {
|
||||
border-left: 1px solid transparent;
|
||||
}
|
||||
|
||||
.tab:before {
|
||||
content: '\2192';
|
||||
}
|
||||
|
||||
.space {
|
||||
border-bottom-width: 0.15rem;
|
||||
border-bottom-style: dashed;
|
||||
100% {
|
||||
border-left: 1px solid white;
|
||||
}
|
||||
}
|
||||
|
||||
+40
-20
@@ -4,13 +4,14 @@ import './App.css';
|
||||
const KEYS_TO_DISABLE = ['Backspace', 'Shift', 'Alt', 'Control', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'Escape', 'Delete', 'PageDown', 'PageUp', 'Home', 'End', 'Insert', 'WakeUp', 'Pause', 'ScrollLock', 'ContextMenu', 'BrowserForward', 'BrowserBack', 'CapsLock', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
|
||||
|
||||
function App() {
|
||||
// TODO: Cleanup the file and create utils for spacing and trimming the code properly.
|
||||
const [code, setCode] = useState('');
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const [characters, setCharacters] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
(async function() {
|
||||
const response = await fetch('http://localhost:5000/generate?lang=golang&lines=10');
|
||||
const response = await fetch('http://localhost:5000/generate?lang=julia&lines=10');
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
@@ -21,6 +22,7 @@ function App() {
|
||||
|
||||
if (done) {
|
||||
setLoaded(true);
|
||||
setCode(prev => prev.replace(/\s\n/g, '\n'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -34,17 +36,20 @@ function App() {
|
||||
if (!loaded) return;
|
||||
if (characters.length === code.length) return;
|
||||
if (KEYS_TO_DISABLE.includes(event.key)) return;
|
||||
if (code[characters.length] === '\n')
|
||||
|
||||
const char = code[characters.length];
|
||||
|
||||
if (/^\n$/.test(char))
|
||||
return setCharacters(
|
||||
characters.concat(event.key === 'Enter')
|
||||
);
|
||||
if (code[characters.length] === '\t')
|
||||
if (/^(\s|\t)$/.test(char))
|
||||
return setCharacters(
|
||||
characters.concat(event.key === 'Tab')
|
||||
characters.concat(['Space', 'Tab'].includes(event.key))
|
||||
);
|
||||
|
||||
setCharacters(
|
||||
characters.concat(event.key === code[characters.length])
|
||||
characters.concat(event.key === char)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -55,30 +60,45 @@ function App() {
|
||||
}, [loaded, characters]);
|
||||
|
||||
function renderCharacterClassName(index) {
|
||||
if (index === characters.length) return 'highlight'
|
||||
if (typeof characters[index] === 'undefined') return 'pending'
|
||||
if (!characters[index]) return 'incorrect'
|
||||
const typed = characters[index];
|
||||
|
||||
return 'correct'
|
||||
if (loaded && index === characters.length) return 'highlight';
|
||||
if (typeof typed === 'undefined') return 'pending';
|
||||
if (!typed) return 'incorrect';
|
||||
|
||||
return 'correct';
|
||||
}
|
||||
|
||||
// TODO: Remove rendering of spacing characters and render a cursor with the highlight instead.
|
||||
// TODO: Or look into pretty printing libraries.
|
||||
function renderSpacingCharacter(char) {
|
||||
if (/^\n$/.test(char)) return 'enter'
|
||||
if (/^\t$/.test(char)) return 'tab'
|
||||
if (/^\s$/.test(char)) return 'space'
|
||||
if (/^\n$/.test(char)) return '\n';
|
||||
if (/^(\s|\t)$/.test(char)) return '\u00A0'
|
||||
|
||||
return ''
|
||||
return char;
|
||||
}
|
||||
|
||||
function renderClassName(index, char) {
|
||||
return `${renderCharacterClassName(index)} ${renderSpacingCharacter(char)}`.trim();
|
||||
function renderClassName(index) {
|
||||
return `${renderCharacterClassName(index)}`.trim();
|
||||
}
|
||||
|
||||
return <div className='container'>{code.split('').map((char, index) => (
|
||||
<span className={renderClassName(index, char)} key={char + index}>{char}</span>
|
||||
))}</div>;
|
||||
function renderCharacter(char, index) {
|
||||
const rendered = renderSpacingCharacter(char);
|
||||
|
||||
if (/^\n$/.test(rendered)) {
|
||||
return <span className={renderClassName(index)} key={char + index}><br /></span>
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={renderClassName(index)} key={char + index}>
|
||||
{rendered}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='container'>
|
||||
{code.split('').map((char, index) => renderCharacter(char, index))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
+2
-2
@@ -41,9 +41,9 @@ func main() {
|
||||
|
||||
ollamaCtx := context.Background()
|
||||
content := []llms.MessageContent{
|
||||
llms.TextParts(llms.ChatMessageTypeSystem, `You are only a code generator. You must not respond with anything else but code and do not format with code fences. Always use tabs instead of spaces.`),
|
||||
llms.TextParts(llms.ChatMessageTypeSystem, `You are only a code generator. You must not respond with anything else but code and do not format with code fences. Always use spaces instead of tabs.`),
|
||||
llms.TextParts(llms.ChatMessageTypeHuman, fmt.Sprintf(`
|
||||
Generate max %d lines of code without any unncessary formatting from a well known open source project in the %s programming language. First line should always be a code comment in the used language in this format: "// Language/Project"`, lines, lang)),
|
||||
Generate max %d lines of code without any unncessary formatting from a well known open source project in the %s programming language.`, lines, lang)),
|
||||
}
|
||||
|
||||
if _, err := llm.GenerateContent(ollamaCtx, content, llms.WithStreamingFunc(func(streamCtx context.Context, chunk []byte) error {
|
||||
|
||||
Reference in New Issue
Block a user