Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions src/cm/indentedLineWrapping.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
EditorState,
type Extension,
Facet,
RangeSetBuilder,
StateEffect,
} from "@codemirror/state";
Expand All @@ -13,15 +14,26 @@ import {
} from "@codemirror/view";

const wrapWidth = StateEffect.define<number>();
export type WrappingIndent = "none" | "same" | "indent" | "deepIndent";
const wrappingIndent = Facet.define<WrappingIndent, WrappingIndent>({
combine: (values) => values[0] ?? "same",
});

/** Keep tab stops on the first visual row unchanged by the negative indent. */
export function wrappedIndentColumns(
text: string,
tabSize: number,
limit: number,
mode: WrappingIndent = "same",
): number {
// Unindented/minified lines need no tab scan, even when they are megabytes long.
if (limit <= 0 || (text[0] !== " " && text[0] !== "\t")) return 0;
const extra =
mode === "indent" ? tabSize : mode === "deepIndent" ? 2 * tabSize : 0;
if (mode === "none" || limit <= 0) return 0;
if (text[0] !== " " && text[0] !== "\t") {
// Extra levels are whole tab stops, so content tabs cannot affect them.
// Keep the width cap tab-aligned too, avoiding a scan even in narrow panes.
return Math.min(extra, Math.floor(limit / tabSize) * tabSize);
}
// Include content tabs deliberately: negative text-indent changes the origin
// of every tab stop on the first visual row. For " key\tvalue", using 2ch
// shifts "value" left by two columns in Chromium; 4ch preserves its position.
Expand All @@ -36,7 +48,7 @@ export function wrappedIndentColumns(
else break;
if (columns >= cap) return cap;
}
return Math.min(cap, Math.ceil(columns / step) * step);
return Math.min(cap, Math.ceil((columns + extra) / step) * step);
}

interface CachedIndent {
Expand All @@ -51,6 +63,7 @@ function decorate(
): { decorations: DecorationSet; cache: Map<number, CachedIndent> } {
const builder = new RangeSetBuilder<Decoration>();
const tabSize = view.state.facet(EditorState.tabSize);
const mode = view.state.facet(wrappingIndent);
const cache = new Map<number, CachedIndent>();
const styles = new Map<number, Decoration>();
let lastLine = -1;
Expand All @@ -60,7 +73,7 @@ function decorate(
if (line.from > lastLine) {
let entry = previous.get(line.from);
if (!entry || entry.text !== line.text) {
const columns = wrappedIndentColumns(line.text, tabSize, limit);
const columns = wrappedIndentColumns(line.text, tabSize, limit, mode);
let decoration = columns ? styles.get(columns) : null;
if (columns && !decoration) {
decoration = Decoration.line({
Expand Down Expand Up @@ -133,7 +146,10 @@ const plugin = ViewPlugin.fromClass(
const tabSizeChanged =
update.startState.facet(EditorState.tabSize) !==
update.state.facet(EditorState.tabSize);
if (changed || tabSizeChanged) {
const modeChanged =
update.startState.facet(wrappingIndent) !==
update.state.facet(wrappingIndent);
if (changed || tabSizeChanged || modeChanged) {
this.cache.clear();
} else if (update.docChanged) {
// Keep unchanged visible lines cached when earlier edits shift them.
Expand All @@ -148,7 +164,8 @@ const plugin = ViewPlugin.fromClass(
changed ||
update.docChanged ||
update.viewportChanged ||
tabSizeChanged
tabSizeChanged ||
modeChanged
) {
const result = decorate(update.view, this.limit, this.cache);
this.decorations = result.decorations;
Expand All @@ -168,9 +185,13 @@ const plugin = ViewPlugin.fromClass(
* tabs occur after the leading whitespace. Oversized indents are capped
* at half the available columns so narrow panes still have room for content.
*/
export function indentedLineWrapping(): Extension {
export function indentedLineWrapping(mode: WrappingIndent = "same"): Extension {
if (mode === "none") return EditorView.lineWrapping;
// Settings imported from older or manually edited files may be invalid.
if (mode !== "indent" && mode !== "deepIndent") mode = "same";
return [
EditorView.lineWrapping,
wrappingIndent.of(mode),
plugin,
EditorView.baseTheme({
".cm-line.cm-wrap-indent": {
Expand Down
7 changes: 6 additions & 1 deletion src/lang/ar-ye.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "يجب ألا يتجاوز التقييم {max} حرفًا.",
"plugin-review:error-downvote-comment": "أخبر المطوّر بما يمكن تحسينه.",
"plugin-review:error-empty": "أضف تعليقًا أو اختر «أعجبني».",
"plugin-review:unrated": "غير مقيّم"
"plugin-review:unrated": "غير مقيّم",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
Comment thread
bajrangCoder marked this conversation as resolved.
}
7 changes: 6 additions & 1 deletion src/lang/be-by.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "Водгук павінен змяшчаць не больш за {max} сімвалаў.",
"plugin-review:error-downvote-comment": "Раскажыце распрацоўшчыку, што можна палепшыць.",
"plugin-review:error-empty": "Дадайце каментарый або выберыце «Падабаецца».",
"plugin-review:unrated": "Без ацэнкі"
"plugin-review:unrated": "Без ацэнкі",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/bn-bd.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "পর্যালোচনা {max} অক্ষর বা তার কম হতে হবে।",
"plugin-review:error-downvote-comment": "কী উন্নত করা যায় তা ডেভেলপারকে জানান।",
"plugin-review:error-empty": "একটি মন্তব্য যোগ করুন বা পছন্দ নির্বাচন করুন।",
"plugin-review:unrated": "এখনও মূল্যায়ন নেই"
"plugin-review:unrated": "এখনও মূল্যায়ন নেই",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/cs-cz.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "Recenze může mít nejvýše {max} znaků.",
"plugin-review:error-downvote-comment": "Sdělte vývojáři, co by se dalo zlepšit.",
"plugin-review:error-empty": "Přidejte komentář nebo zvolte Líbí se mi.",
"plugin-review:unrated": "Nehodnoceno"
"plugin-review:unrated": "Nehodnoceno",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/de-de.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "Die Bewertung darf höchstens {max} Zeichen lang sein.",
"plugin-review:error-downvote-comment": "Sage dem Entwickler, was verbessert werden könnte.",
"plugin-review:error-empty": "Füge einen Kommentar hinzu oder wähle „Gefällt mir“.",
"plugin-review:unrated": "Nicht bewertet"
"plugin-review:unrated": "Nicht bewertet",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
5 changes: 5 additions & 0 deletions src/lang/en-us.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@
"success": "Success",
"tab size": "Tab size",
"text wrap": "Text wrap / Word wrap",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size.",
"theme": "Theme",
"title-listfiles": "List files",
"ui zoom": "UI zoom",
Expand Down
7 changes: 6 additions & 1 deletion src/lang/es-sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "La reseña debe tener {max} caracteres o menos.",
"plugin-review:error-downvote-comment": "Dile al desarrollador qué podría mejorar.",
"plugin-review:error-empty": "Agrega un comentario o elige Me gusta.",
"plugin-review:unrated": "Sin calificar"
"plugin-review:unrated": "Sin calificar",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/fr-fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "L’avis doit contenir au maximum {max} caractères.",
"plugin-review:error-downvote-comment": "Indiquez au développeur ce qui pourrait être amélioré.",
"plugin-review:error-empty": "Ajoutez un commentaire ou choisissez J’aime.",
"plugin-review:unrated": "Non évalué"
"plugin-review:unrated": "Non évalué",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/he-il.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "הביקורת צריכה להכיל עד {max} תווים.",
"plugin-review:error-downvote-comment": "ספר למפתח מה אפשר לשפר.",
"plugin-review:error-empty": "הוסף תגובה או בחר באהבתי.",
"plugin-review:unrated": "ללא דירוג"
"plugin-review:unrated": "ללא דירוג",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/hi-in.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "समीक्षा {max} वर्णों या उससे कम की होनी चाहिए।",
"plugin-review:error-downvote-comment": "डेवलपर को बताएँ कि क्या बेहतर किया जा सकता है।",
"plugin-review:error-empty": "टिप्पणी जोड़ें या पसंद चुनें।",
"plugin-review:unrated": "अभी रेटिंग नहीं"
"plugin-review:unrated": "अभी रेटिंग नहीं",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/hu-hu.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "A megjegyzés szövege legfeljebb {max} karakter lehet.",
"plugin-review:error-downvote-comment": "Írja meg a fejlesztőknek, hogy min lehetne javítani.",
"plugin-review:error-empty": "Adjon hozzá megjegyzést vagy válassza a „Tetszik” lehetőséget.",
"plugin-review:unrated": "Még nem értékelte senki"
"plugin-review:unrated": "Még nem értékelte senki",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/id-id.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "Ulasan harus terdiri dari {max} karakter atau kurang.",
"plugin-review:error-downvote-comment": "Beri tahu developer apa yang dapat ditingkatkan.",
"plugin-review:error-empty": "Tambahkan komentar atau pilih Suka.",
"plugin-review:unrated": "Belum dinilai"
"plugin-review:unrated": "Belum dinilai",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
6 changes: 6 additions & 0 deletions src/lang/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ declare type LangStrings = {
"success": string;
"tab size": string;
"text wrap": string;
"wrapped line indent": string;
"wrap-indent-same": string;
"wrap-indent-indent": string;
"wrap-indent-deep": string;
"settings-info-editor-wrapping-indent": string;
"theme": string;
"title-listfiles": string;
"ui zoom": string;
Expand Down Expand Up @@ -772,6 +777,7 @@ declare type LangStrings = {
"app font": string;
"app icon": string;
"app icon changed": string;
"app icon change warning": string;
"settings-info-app-font-family": string;
"settings-info-app-icon": string;
"unsaved selected tabs warning": string;
Expand Down
7 changes: 6 additions & 1 deletion src/lang/ir-fa.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "نظر باید حداکثر {max} نویسه باشد.",
"plugin-review:error-downvote-comment": "به توسعه‌دهنده بگویید چه چیزی می‌تواند بهتر شود.",
"plugin-review:error-empty": "یک دیدگاه بنویسید یا «پسندیدم» را انتخاب کنید.",
"plugin-review:unrated": "بدون امتیاز"
"plugin-review:unrated": "بدون امتیاز",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/it-it.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "La recensione deve contenere al massimo {max} caratteri.",
"plugin-review:error-downvote-comment": "Spiega allo sviluppatore cosa potrebbe essere migliorato.",
"plugin-review:error-empty": "Aggiungi un commento o scegli Mi piace.",
"plugin-review:unrated": "Non valutato"
"plugin-review:unrated": "Non valutato",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/ja-jp.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "レビューは {max} 文字以内で入力してください。",
"plugin-review:error-downvote-comment": "改善してほしい点を開発者に伝えてください。",
"plugin-review:error-empty": "コメントを追加するか、高評価を選んでください。",
"plugin-review:unrated": "未評価"
"plugin-review:unrated": "未評価",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/ko-kr.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "리뷰는 {max}자 이하여야 합니다.",
"plugin-review:error-downvote-comment": "개발자에게 개선할 점을 알려 주세요.",
"plugin-review:error-empty": "댓글을 추가하거나 좋아요를 선택하세요.",
"plugin-review:unrated": "평가 없음"
"plugin-review:unrated": "평가 없음",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/ln-ln.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "Review must be {max} characters or less.",
"plugin-review:error-downvote-comment": "Tell the developer what could be improved.",
"plugin-review:error-empty": "Add a comment or choose thumbs up.",
"plugin-review:unrated": "Unrated"
"plugin-review:unrated": "Unrated",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/ml-in.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "അവലോകനം {max} അക്ഷരങ്ങളോ അതിൽ കുറവോ ആയിരിക്കണം.",
"plugin-review:error-downvote-comment": "എന്താണ് മെച്ചപ്പെടുത്താനാകുന്നതെന്ന് ഡെവലപ്പറോട് പറയുക.",
"plugin-review:error-empty": "ഒരു അഭിപ്രായം ചേർക്കുക അല്ലെങ്കിൽ ഇഷ്ടപ്പെട്ടു തിരഞ്ഞെടുക്കുക.",
"plugin-review:unrated": "വിലയിരുത്തിയിട്ടില്ല"
"plugin-review:unrated": "വിലയിരുത്തിയിട്ടില്ല",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
7 changes: 6 additions & 1 deletion src/lang/mm-unicode.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,5 +876,10 @@
"plugin-review:error-max-length": "သုံးသပ်ချက်သည် စာလုံးရေ {max} လုံး သို့မဟုတ် ထိုထက်နည်းရမည်။",
"plugin-review:error-downvote-comment": "မည်သည့်အရာကို ပိုကောင်းအောင်လုပ်နိုင်ကြောင်း developer ကို ပြောပါ။",
"plugin-review:error-empty": "မှတ်ချက်ထည့်ပါ သို့မဟုတ် ကြိုက်သည်ကို ရွေးပါ။",
"plugin-review:unrated": "အဆင့်မသတ်မှတ်ရသေးပါ"
"plugin-review:unrated": "အဆင့်မသတ်မှတ်ရသေးပါ",
"wrapped line indent": "Word wrap indentation",
"wrap-indent-same": "Same",
"wrap-indent-indent": "Indent (+1 level)",
"wrap-indent-deep": "Deep indent (+2 levels)",
"settings-info-editor-wrapping-indent": "Choose whether wrapped text starts at the left edge, matches the original line's indentation, or is indented further. Each extra level uses your tab size."
}
Loading