diff --git a/README.md b/README.md index 68f44c0..4f8f5a4 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,9 @@ restauração) e autenticação por **token** (Bearer para API / cookie HttpOnly - **Marcador de coluna** customizável — padrão **80** (linha vertical no editor, exibida com quebra de linha desligada, como no Mousepad/gedit). - **Quebrar linha** ligado/desligável (alternável também pelo menu Exibir). + - **Tecla Tab**: insere N espaços (padrão **4**, configurável 1–16) **ou** o caractere de + tabulação `\t`; o valor também define a largura exibida do `\t` (`tab-size`) no editor e no + realce, mantendo as camadas alinhadas. - **Fonte** (DejaVu Sans Mono, Ubuntu Mono, Cascadia Code, Liberation Mono, Courier New ou monoespaçada do sistema) e **tamanho** (10–32 px). - **Esquema de cores / tema**: Claro (Greybird), Escuro (Adwaita), Solarizado claro e diff --git a/web/css/app.css b/web/css/app.css index 58e1d61..5cc2a5f 100644 --- a/web/css/app.css +++ b/web/css/app.css @@ -309,7 +309,7 @@ body.no-gutter #gutter { display: none; } white-space: pre-wrap; overflow-wrap: break-word; pointer-events: none; - tab-size: 4; + tab-size: var(--tab-size, 4); } #hl.nowrap { white-space: pre; overflow-wrap: normal; } .hl-line { min-height: var(--line-h); } @@ -339,7 +339,7 @@ body.no-gutter #gutter { display: none; } background: transparent; color: transparent; caret-color: var(--fg); - tab-size: 4; + tab-size: var(--tab-size, 4); } #editor:focus { outline: none; } #editor::selection { background: rgba(53, 132, 228, .30); } @@ -894,6 +894,7 @@ html[data-theme="solar-escuro"] #revisions-list li:hover { background: #0c4450; background: var(--panel); color: var(--fg); } +.dialog .row select.compact { flex: 0 1 auto; } .dialog .num { width: 74px; flex: none; } /* diálogos no celular (depois das regras base de .dialog) */ diff --git a/web/index.html b/web/index.html index 640a986..6ce802d 100644 --- a/web/index.html +++ b/web/index.html @@ -34,6 +34,14 @@ +
Fonte e tema diff --git a/web/js/app.js b/web/js/app.js index 06df633..e84ef24 100644 --- a/web/js/app.js +++ b/web/js/app.js @@ -687,11 +687,11 @@ refreshPreviewIfOpen(); }); - // Tab insere 4 espaços em vez de sair do textarea. + // Tab: insere N espaços ou \t conforme as preferências (nunca troca de foco). E.editor.addEventListener('keydown', (e) => { - if (e.key === 'Tab') { + if (e.key === 'Tab' && !e.ctrlKey && !e.metaKey && !e.altKey) { e.preventDefault(); - insertText(' '); + insertText(prefs.tabSpaces ? ' '.repeat(prefs.tabSize) : '\t'); } }); @@ -819,7 +819,7 @@ /* ------------------------------------------------------- preferências */ const PREFS_KEY = 'notas_prefs'; - const PREFS_DEFAULT = { gutter: true, wrap: true, colmark: true, col: 80, hl: true, font: 'mono', size: 14, theme: 'claro' }; + const PREFS_DEFAULT = { gutter: true, wrap: true, colmark: true, col: 80, hl: true, tabSpaces: true, tabSize: 4, font: 'mono', size: 14, theme: 'claro' }; const THEMES = ['claro', 'escuro', 'solar-claro', 'solar-escuro']; const FONT_STACKS = { mono: '"DejaVu Sans Mono", "Ubuntu Mono", "Cascadia Code", Consolas, monospace', @@ -839,6 +839,7 @@ } p.col = Math.min(320, Math.max(20, Math.round(p.col) || 80)); p.size = Math.min(32, Math.max(10, Math.round(p.size) || 14)); + p.tabSize = Math.min(16, Math.max(1, Math.round(p.tabSize) || 4)); if (!FONT_STACKS[p.font]) p.font = 'mono'; if (!THEMES.includes(p.theme)) p.theme = 'claro'; return p; @@ -852,6 +853,7 @@ root.style.setProperty('--editor-font', FONT_STACKS[prefs.font]); root.style.setProperty('--editor-size', prefs.size + 'px'); root.style.setProperty('--line-h', Math.round(prefs.size * 1.55) + 'px'); + root.style.setProperty('--tab-size', String(prefs.tabSize)); root.dataset.theme = prefs.theme; document.body.classList.toggle('no-gutter', !prefs.gutter); if (prefs.wrap) E.editor.removeAttribute('wrap'); @@ -1066,6 +1068,7 @@ const PF = { overlay: $('#prefs-overlay'), form: $('#prefs-form'), gutter: $('#pf-gutter'), wrap: $('#pf-wrap'), colmark: $('#pf-colmark'), col: $('#pf-col'), hl: $('#pf-hl'), + tabmode: $('#pf-tabmode'), tabsize: $('#pf-tabsize'), font: $('#pf-font'), size: $('#pf-size'), theme: $('#pf-theme'), reset: $('#pf-reset'), cancel: $('#pf-cancel'), }; @@ -1077,6 +1080,8 @@ PF.colmark.checked = prefs.colmark; PF.col.value = prefs.col; PF.hl.checked = prefs.hl; + PF.tabmode.value = prefs.tabSpaces ? 'spaces' : 'tab'; + PF.tabsize.value = prefs.tabSize; PF.font.value = prefs.font; PF.size.value = prefs.size; PF.theme.value = prefs.theme; @@ -1088,6 +1093,8 @@ prefs.colmark = PF.colmark.checked; prefs.col = Math.min(320, Math.max(20, parseInt(PF.col.value, 10) || 80)); prefs.hl = PF.hl.checked; + prefs.tabSpaces = PF.tabmode.value !== 'tab'; + prefs.tabSize = Math.min(16, Math.max(1, parseInt(PF.tabsize.value, 10) || 4)); prefs.font = FONT_STACKS[PF.font.value] ? PF.font.value : 'mono'; prefs.size = Math.min(32, Math.max(10, parseInt(PF.size.value, 10) || 14)); prefs.theme = THEMES.includes(PF.theme.value) ? PF.theme.value : 'claro';