feat: Alt+/ autocomplete + auto-continue listes/checkboxes au Enter
- Raccourci: Ctrl+Space → Alt+/ (evite conflit OS) - Enter sur ligne liste (-, *, +) → continue la puce - Enter sur ligne vide (puce sans texte) → termine la liste - Enter sur liste numerotee (1.) → auto-incremente (2.) - Enter sur checkbox (- [ ]) → nouvelle checkbox vide - Aide F1 mise a jour, barre statut mise a jour
This commit is contained in:
@@ -393,7 +393,7 @@ body { font-family: var(--sans); background: var(--bg); color: var(--text); heig
|
|||||||
<!-- Status bar -->
|
<!-- Status bar -->
|
||||||
<div class="stat">
|
<div class="stat">
|
||||||
<div class="stat-left">
|
<div class="stat-left">
|
||||||
<span>Type <strong>/</strong> for commands | <strong>Alt+I</strong> Insert</span>
|
<span>Type <strong>/</strong> for commands | <strong>Alt+/</strong> autocomplete | <strong>Alt+I</strong> Insert</span>
|
||||||
<span>Ctrl+J AI panel</span>
|
<span>Ctrl+J AI panel</span>
|
||||||
<span>Ctrl+S save</span>
|
<span>Ctrl+S save</span>
|
||||||
<span>Ctrl+K link</span>
|
<span>Ctrl+K link</span>
|
||||||
@@ -442,6 +442,9 @@ body { font-family: var(--sans); background: var(--bg); color: var(--text); heig
|
|||||||
<tr><td>Ctrl+S</td><td>Sauvegarder</td></tr>
|
<tr><td>Ctrl+S</td><td>Sauvegarder</td></tr>
|
||||||
<tr><td>Clic sur le titre</td><td>Renommer le fichier</td></tr>
|
<tr><td>Clic sur le titre</td><td>Renommer le fichier</td></tr>
|
||||||
<tr><td>Ctrl+J</td><td>Panneau AI</td></tr>
|
<tr><td>Ctrl+J</td><td>Panneau AI</td></tr>
|
||||||
|
<tr><td>Alt+/</td><td>Autocompletion intelligente</td></tr>
|
||||||
|
<tr><td>Enter (liste)</td><td>Continue la liste (-, *, 1.) et checkboxes</td></tr>
|
||||||
|
<tr><td>Enter (liste vide)</td><td>Termine la liste</td></tr>
|
||||||
</table>
|
</table>
|
||||||
<h3>Slash — Commandes</h3>
|
<h3>Slash — Commandes</h3>
|
||||||
<table>
|
<table>
|
||||||
@@ -1783,15 +1786,63 @@ body { font-family: var(--sans); background: var(--bg); color: var(--text); heig
|
|||||||
else if (e.key === 'Escape') { e.preventDefault(); hideAutocomplete(); }
|
else if (e.key === 'Escape') { e.preventDefault(); hideAutocomplete(); }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Ctrl+Space: force autocomplete
|
// Alt+/ : force autocomplete
|
||||||
if ((e.ctrlKey || e.metaKey) && e.key === ' ') {
|
if (e.altKey && !e.ctrlKey && !e.metaKey && e.key === '/') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
triggerAutocomplete();
|
triggerAutocomplete();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// Auto-trigger on [[ for wikilinks
|
// Auto-trigger on [[ for wikilinks
|
||||||
if (e.key === '[' && ta.selectionStart > 0 && ta.value[ta.selectionStart - 1] === '[') {
|
if (e.key === '[' && ta.selectionStart > 0 && ta.value[ta.selectionStart - 1] === '[') {
|
||||||
setTimeout(triggerAutocomplete, 50);
|
setTimeout(triggerAutocomplete, 50);
|
||||||
}
|
}
|
||||||
|
// Enter: auto-continue lists and checkboxes
|
||||||
|
if (e.key === 'Enter' && !e.shiftKey) {
|
||||||
|
var before = ta.value.slice(0, ta.selectionStart);
|
||||||
|
var after = ta.value.slice(ta.selectionEnd);
|
||||||
|
var lineStart = before.lastIndexOf('\n') + 1;
|
||||||
|
var currentLine = before.slice(lineStart);
|
||||||
|
var indent = (currentLine.match(/^(\s*)/) || [''])[0];
|
||||||
|
// Ordered list: 1. 2. 3. etc
|
||||||
|
var olMatch = currentLine.match(/^(\s*)(\d+)\.\s/);
|
||||||
|
// Unordered list: - * +
|
||||||
|
var ulMatch = currentLine.match(/^(\s*)([-*+])\s/);
|
||||||
|
// Task checkbox: - [ ] or - [x]
|
||||||
|
var taskMatch = currentLine.match(/^(\s*)([-*+])\s+\[([ xX])\]\s/);
|
||||||
|
|
||||||
|
if (taskMatch) {
|
||||||
|
// Continue checkbox (empty, unchecked)
|
||||||
|
e.preventDefault();
|
||||||
|
var newNumber = '';
|
||||||
|
ta.value = before + '\n' + indent + taskMatch[2] + ' [ ] ';
|
||||||
|
ta.setSelectionRange(ta.value.length, ta.value.length);
|
||||||
|
markDirty(); autoHeight(); updateLineNumbers();
|
||||||
|
return;
|
||||||
|
} else if (olMatch) {
|
||||||
|
// Auto-increment ordered list
|
||||||
|
e.preventDefault();
|
||||||
|
var num = parseInt(olMatch[2]) + 1;
|
||||||
|
ta.value = before + '\n' + olMatch[1] + num + '. ';
|
||||||
|
ta.setSelectionRange(ta.value.length, ta.value.length);
|
||||||
|
markDirty(); autoHeight(); updateLineNumbers();
|
||||||
|
return;
|
||||||
|
} else if (ulMatch) {
|
||||||
|
var afterTrim = currentLine.slice(ulMatch[0].length).trim();
|
||||||
|
if (afterTrim.length === 0) {
|
||||||
|
// Empty bullet: remove it and break list
|
||||||
|
e.preventDefault();
|
||||||
|
ta.value = before.slice(0, lineStart) + '\n' + after.slice(after.indexOf('\n') + 1);
|
||||||
|
ta.setSelectionRange(lineStart, lineStart);
|
||||||
|
} else {
|
||||||
|
// Continue bullet
|
||||||
|
e.preventDefault();
|
||||||
|
ta.value = before + '\n' + ulMatch[1] + ulMatch[2] + ' ';
|
||||||
|
ta.setSelectionRange(ta.value.length, ta.value.length);
|
||||||
|
}
|
||||||
|
markDirty(); autoHeight(); updateLineNumbers();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Trigger on triple backtick
|
// Trigger on triple backtick
|
||||||
@@ -1810,7 +1861,7 @@ body { font-family: var(--sans); background: var(--bg); color: var(--text); heig
|
|||||||
console.log('ObsiGate Editor v2 ready');
|
console.log('ObsiGate Editor v2 ready');
|
||||||
console.log(' File: ' + (fileVault ? fileVault + '/' + filePath : 'demo mode'));
|
console.log(' File: ' + (fileVault ? fileVault + '/' + filePath : 'demo mode'));
|
||||||
console.log(' AI: checking...');
|
console.log(' AI: checking...');
|
||||||
console.log(' Type / for commands | Select text for bubble | Ctrl+J AI | Ctrl+S save');
|
console.log(' Type / for commands | Select text for bubble | Alt+/ autocomplete | Ctrl+J AI | Ctrl+S save');
|
||||||
|
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user