"decoration 은 소스를 안 바꾸고 위에 칠해. 그 한 속성이 메커니즘 하나가 전부를 할 수 있는 이유야."
두 종류의 decoration
CodeMirror 6 은 소스 위에 시각 레이어를 더하는 방법을 딱 둘 줘. mark decoration 은 텍스트 범위에 스타일을 붙여 — 4–8 문자를 bold, 12–16 문자를 빨간 밑줄. widget decoration 은 위치에 UI 조각을 삽입해 — 단어 뒤 여백 노트, 줄 밑 제안 블록 통째. mark 는 있는 걸 스타일하고, widget 은 없는 걸 삽입해. 둘이 합쳐 기능이 원할 모든 '뭔가 추가로 보여주기' 를 커버해.
소스 위에 칠하지, 절대 mutate 안 해
decoration 을 강력하게 만드는 속성은 그게 안 하는 것이야. 절대 문서를 안 바꿔. bold mark 는 텍스트에 서식을 삽입하지 않아. 이미 거기 있는 문자를 bold 로 렌더할 뿐. widget 은 파일에 안 써. 뷰의 한 지점에 UI 를 칠할 뿐. 소스 문자열은 그대로야. decoration 은 매 편집마다 문서에서 DecorationSet 을 다시 계산하는 StateField 에 살아:
const decoField = StateField.define<DecorationSet>({
create: () => Decoration.none,
update: (deco, tr) => buildDecorations(tr.state), // 범위 -> mark + widget
provide: (f) => EditorView.decorations.from(f),
});
원시 요소 하나, 모든 '추가로 보여주기' 기능
트릭 전체가 여기 있어. decoration 이 모델을 안 건드리고 레이어를 더하니까, '사용자 텍스트 위에 뭔가 추가로 보여주기' 를 뜻하는 어떤 기능도 같은 원시 요소로 줄어들어. 범위 집합을 계산하고, mark 나 widget 을 붙이고, CM6 이 렌더하게 둬. Live Preview 는 범위-to-mark. voice underline 은 범위-to-mark-플러스-widget. CMD+K 는 제안을 담은 widget. 관련 없어 보이는 세 기능이, 밑에선, 입력만 다른 같은 계산이야. 그게 트랙 전체의 씨앗이야.