Des tonnes de modifications notamment VIM / Couleurs / typos

This commit is contained in:
2025-11-11 15:41:51 +01:00
parent 439880b08f
commit 6face7a02f
59 changed files with 7857 additions and 960 deletions

View File

@ -6,6 +6,18 @@ import { oneDark } from '@codemirror/theme-one-dark';
import { keymap } from '@codemirror/view';
import { indentWithTab } from '@codemirror/commands';
// Import du mode Vim
let vimExtension = null;
(async () => {
try {
const { vim } = await import('@replit/codemirror-vim');
vimExtension = vim;
console.log('✅ Vim extension loaded and ready');
} catch (error) {
console.warn('⚠️ Vim extension not available:', error.message);
}
})();
/**
* MarkdownEditor - Éditeur Markdown avec preview en temps réel
*/
@ -48,56 +60,88 @@ class MarkdownEditor {
});
}
// Initialiser CodeMirror 6
const startState = EditorState.create({
doc: this.textarea.value,
extensions: [
basicSetup,
markdown(),
oneDark,
keymap.of([indentWithTab]),
EditorView.updateListener.of((update) => {
if (update.docChanged) {
// Debounce la mise à jour du preview
if (this._updateTimeout) {
clearTimeout(this._updateTimeout);
}
this._updateTimeout = setTimeout(() => {
this.updatePreview();
}, 150);
// Initialiser l'éditeur (avec ou sans Vim)
this.initEditor();
}
// Auto-save logic
if (this._autoSaveTimeout) {
clearTimeout(this._autoSaveTimeout);
}
this._autoSaveTimeout = setTimeout(() => {
const form = this.textarea.closest('form');
if (form) {
const saveStatus = document.getElementById('auto-save-status');
if (saveStatus) {
saveStatus.textContent = 'Sauvegarde...';
}
// Synchroniser le contenu de CodeMirror vers le textarea
this.syncToTextarea();
form.requestSubmit();
}
}, 2000); // Auto-save after 2 seconds of inactivity
getExtensions() {
const extensions = [
basicSetup,
markdown(),
oneDark,
keymap.of([indentWithTab]),
EditorView.updateListener.of((update) => {
if (update.docChanged) {
// Debounce la mise à jour du preview
if (this._updateTimeout) {
clearTimeout(this._updateTimeout);
}
}),
// Keymap for Ctrl/Cmd+S
keymap.of([{
key: "Mod-s",
run: () => {
this._updateTimeout = setTimeout(() => {
this.updatePreview();
}, 150);
// Auto-save logic
if (this._autoSaveTimeout) {
clearTimeout(this._autoSaveTimeout);
}
this._autoSaveTimeout = setTimeout(() => {
const form = this.textarea.closest('form');
if (form) {
const saveStatus = document.getElementById('auto-save-status');
if (saveStatus) {
saveStatus.textContent = 'Sauvegarde...';
}
// Synchroniser le contenu de CodeMirror vers le textarea
this.syncToTextarea();
form.requestSubmit();
}
return true;
}, 2000); // Auto-save after 2 seconds of inactivity
}
}),
// Keymap for Ctrl/Cmd+S
keymap.of([{
key: "Mod-s",
run: () => {
const form = this.textarea.closest('form');
if (form) {
// Synchroniser le contenu de CodeMirror vers le textarea
this.syncToTextarea();
form.requestSubmit();
}
}])
]
return true;
}
}])
];
// Ajouter l'extension Vim si activée et disponible
if (window.vimModeManager && window.vimModeManager.isEnabled()) {
if (vimExtension) {
extensions.push(vimExtension());
console.log('✅ Vim mode enabled in editor');
} else {
console.warn('⚠️ Vim mode requested but extension not loaded yet');
}
}
return extensions;
}
initEditor() {
const currentContent = this.editorView
? this.editorView.state.doc.toString()
: this.textarea.value;
const extensions = this.getExtensions();
// Détruire l'ancien éditeur si il existe
if (this.editorView) {
this.editorView.destroy();
}
// Initialiser CodeMirror 6
const startState = EditorState.create({
doc: currentContent,
extensions
});
this.editorView = new EditorView({
@ -160,6 +204,13 @@ class MarkdownEditor {
// Initial preview update
this.updatePreview();
// Initialiser les SlashCommands si ce n'est pas déjà fait
if (this.editorView && !window.currentSlashCommands) {
window.currentSlashCommands = new SlashCommands({
editorView: this.editorView
});
}
}
stripFrontMatter(markdownContent) {
@ -242,6 +293,11 @@ class MarkdownEditor {
this.textarea = null;
this.preview = null;
}
async reloadWithVimMode() {
console.log('Reloading editor with Vim mode...');
await this.initEditor();
}
}
// Global instances
@ -360,9 +416,9 @@ class SlashCommands {
this.palette.id = 'slash-commands-palette';
this.palette.style.cssText = `
position: fixed;
background: #161b22;
background-color: #161b22 !important;
border: 1px solid #58a6ff;
background: var(--bg-secondary);
background-color: var(--bg-secondary) !important;
border: 1px solid var(--border-primary);
list-style: none;
padding: 0.5rem;
margin: 0;
@ -372,7 +428,7 @@ class SlashCommands {
min-width: 220px;
max-height: 320px;
overflow-y: auto;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -4px rgba(0, 0, 0, 0.3), 0 0 20px rgba(88, 166, 255, 0.2);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -4px rgba(0, 0, 0, 0.3);
opacity: 1 !important;
`;
@ -477,14 +533,14 @@ class SlashCommands {
filteredCommands.forEach((cmd, index) => {
const li = document.createElement('li');
li.innerHTML = `<span style="color: #7d8590; margin-right: 0.5rem;">⌘</span>/${cmd.name}`;
li.innerHTML = `<span style="color: var(--text-muted); margin-right: 0.5rem;">⌘</span>/${cmd.name}`;
const isSelected = index === this.selectedIndex;
li.style.cssText = `
padding: 0.5rem 0.75rem;
cursor: pointer;
color: ${isSelected ? 'white' : '#e6edf3'};
background: ${isSelected ? 'linear-gradient(135deg, #58a6ff, #8b5cf6)' : 'transparent'};
color: ${isSelected ? 'var(--text-primary)' : 'var(--text-secondary)'};
background: ${isSelected ? 'var(--accent-primary)' : 'transparent'};
border-radius: 4px;
margin: 4px 0;
transition: all 150ms ease;
@ -632,12 +688,7 @@ function initializeMarkdownEditor(context) {
const markdownEditor = new MarkdownEditor(textarea, preview);
window.currentMarkdownEditor = markdownEditor;
if (markdownEditor.editorView) {
const slashCommands = new SlashCommands({
editorView: markdownEditor.editorView
});
window.currentSlashCommands = slashCommands;
}
// Note: SlashCommands sera créé automatiquement dans initEditor() qui est async
}
/**