본문으로 건너뛰기
AZ Tools

EditorConfig 테스터

.editorconfig는 위에서 아래로 읽는 파일이 아니라, 대상 파일에서 위쪽 디렉터리로 거슬러 올라가며 읽는 파일입니다. 소스 파일과 디스크 루트 사이의 모든 디렉터리가 설정 파일을 가질 수 있고, 탐색은 서두에 root = true가 적힌 파일에서만 멈춥니다. 속성별로는 가장 가까운 파일이 이기고, 한 파일 안에서는 마지막에 일치한 섹션이 이깁니다. CSS 같은 우선순위 개념은 없습니다. "이 파일은 왜 공백 네 칸이 되지?"라는 질문의 답이 지금 보고 있는 줄에 없는 이유가 바로 이것입니다. 이 도구는 설정 파일(여러 개라면 각각 "# path: src/.editorconfig" 표시 줄로 구분)과 파일 경로 목록을 받아, 경로마다 최종 속성 집합과 각 값을 만든 파일·줄 번호·섹션 글롭, 위로 올라가며 참조한 설정 파일의 순서, 그리고 root = true가 그 사슬을 끊은 지점을 보여줍니다. 글롭 규칙은 fnmatch도 gitignore도 아닙니다. *는 슬래시에서 멈추고 **는 슬래시를 넘어가며, ?는 슬래시가 아닌 한 글자입니다. [abc]와 [!abc]는 문자 클래스지만 안에 슬래시가 들어가는 순간 클래스가 아니게 됩니다. {js,ts}는 선택지지만 쉼표 없는 {js}는 문자 그대로 세 글자를 뜻하고, {1..10}은 음수를 포함한 정수 범위이며 앞자리 0이 붙으면 일치하지 않습니다. 사람들이 가장 많이 틀리는 규칙은 따로 있습니다. 끝이 아닌 곳에 슬래시가 하나라도 있는 글롭은 그 .editorconfig가 있는 디렉터리를 기준으로 고정되고, 슬래시가 없는 글롭은 깊이와 무관하게 파일 이름만 봅니다. 결과에 나오는 값 중 셋은 어느 파일에도 적혀 있지 않은 경우가 많습니다. indent_style이 tab이고 크기가 없으면 indent_size는 tab이 되고, indent_size가 숫자인데 tab_width가 없으면 tab_width가 그 숫자를 복사하며, indent_size가 tab인데 tab_width가 있으면 indent_size가 그 숫자를 가져옵니다. 병합이 끝난 뒤에 적용되므로 루트 설정의 tab_width가 세 단계 아래에서 쓴 indent_size에 섞여 들어갈 수 있습니다. 발견 패널은 설정 파일이 스스로 알려 주지 못하는 문제를 짚어 줍니다. 어떤 경로와도 맞지 않는 섹션, 설정했지만 언제나 밀리는 값, indent_style 없는 indent_size, 공백이 매칭 대상에 포함되는 {js, ts}, 중복된 섹션 이름, 표준 아홉 개에 없는 키, 허용되지 않는 값, 첫 섹션보다 앞에 있어 조용히 버려지는 속성, 그리고 홈 디렉터리의 .editorconfig까지 살려 두는 root = true 누락입니다. 알려 주지 못하는 것도 있습니다. 편집기가 이 규칙을 실제로 지키는지는 플러그인마다 다르며 max_line_length나 일부 charset 값은 무시되는 경우가 많습니다. unset은 값을 지우라는 신호로 플러그인에 그대로 전달됩니다. "일치하는 경로 없음"도 붙여넣은 목록 안에서만 참이므로 대표적인 경로를 함께 넣어 보세요. 모든 처리는 브라우저 안에서만 이루어집니다.

설정 파일

2

섹션

6

경로

8

발견

1

src/app.js

탐색 경로: .editorconfig · root = true에서 중단됨

속성설정한 곳
charsetutf-8.editorconfig:4 [*]
end_of_linelf.editorconfig:5 [*]
indent_size2.editorconfig:8 [*]
indent_stylespace.editorconfig:7 [*]
insert_final_newlinetrue.editorconfig:6 [*]
tab_width2유도된 값 — 어느 파일에도 적혀 있지 않음.editorconfig:8 [*]tab_width가 없어서 indent_size 값을 그대로 가져옴
lib/util.js

탐색 경로: .editorconfig · root = true에서 중단됨

속성설정한 곳
charsetutf-8.editorconfig:4 [*]
end_of_linelf.editorconfig:5 [*]
indent_size4.editorconfig:20 [lib/**.js]덮어쓴 설정 .editorconfig:8
indent_stylespace.editorconfig:7 [*]
insert_final_newlinetrue.editorconfig:6 [*]
tab_width4유도된 값 — 어느 파일에도 적혀 있지 않음.editorconfig:20 [lib/**.js]tab_width가 없어서 indent_size 값을 그대로 가져옴
lib/deep/util.min.js

탐색 경로: .editorconfig · root = true에서 중단됨

속성설정한 곳
charsetutf-8.editorconfig:4 [*]
end_of_linelf.editorconfig:5 [*]
indent_size4.editorconfig:20 [lib/**.js]덮어쓴 설정 .editorconfig:8
indent_stylespace.editorconfig:7 [*]
insert_final_newlinetrue.editorconfig:6 [*]
tab_width4유도된 값 — 어느 파일에도 적혀 있지 않음.editorconfig:20 [lib/**.js]tab_width가 없어서 indent_size 값을 그대로 가져옴
main.py

탐색 경로: .editorconfig · root = true에서 중단됨

속성설정한 곳
charsetutf-8.editorconfig:4 [*]
end_of_linelf.editorconfig:5 [*]
indent_size4.editorconfig:11 [*.{py,rs}]덮어쓴 설정 .editorconfig:8
indent_stylespace.editorconfig:7 [*]
insert_final_newlinetrue.editorconfig:6 [*]
tab_width4유도된 값 — 어느 파일에도 적혀 있지 않음.editorconfig:11 [*.{py,rs}]tab_width가 없어서 indent_size 값을 그대로 가져옴
Makefile

탐색 경로: .editorconfig · root = true에서 중단됨

속성설정한 곳
charsetutf-8.editorconfig:4 [*]
end_of_linelf.editorconfig:5 [*]
indent_size2.editorconfig:8 [*]
indent_styletab.editorconfig:17 [Makefile]덮어쓴 설정 .editorconfig:7
insert_final_newlinetrue.editorconfig:6 [*]
tab_width2유도된 값 — 어느 파일에도 적혀 있지 않음.editorconfig:8 [*]tab_width가 없어서 indent_size 값을 그대로 가져옴
docs/guide.md

탐색 경로: .editorconfig · root = true에서 중단됨

속성설정한 곳
charsetutf-8.editorconfig:4 [*]
end_of_linelf.editorconfig:5 [*]
indent_size2.editorconfig:8 [*]
indent_stylespace.editorconfig:7 [*]
insert_final_newlinetrue.editorconfig:6 [*]
tab_width2유도된 값 — 어느 파일에도 적혀 있지 않음.editorconfig:8 [*]tab_width가 없어서 indent_size 값을 그대로 가져옴
trim_trailing_whitespacefalse.editorconfig:14 [*.{md, txt}]
notes.txt

탐색 경로: .editorconfig · root = true에서 중단됨

속성설정한 곳
charsetutf-8.editorconfig:4 [*]
end_of_linelf.editorconfig:5 [*]
indent_size2.editorconfig:8 [*]
indent_stylespace.editorconfig:7 [*]
insert_final_newlinetrue.editorconfig:6 [*]
tab_width2유도된 값 — 어느 파일에도 적혀 있지 않음.editorconfig:8 [*]tab_width가 없어서 indent_size 값을 그대로 가져옴
vendor/jquery.js

탐색 경로: vendor/.editorconfig → .editorconfig · root = true에서 중단됨

속성설정한 곳
charsetutf-8.editorconfig:4 [*]
end_of_linelf.editorconfig:5 [*]
indent_size2.editorconfig:8 [*]
indent_styletabvendor/.editorconfig:2 [*]덮어쓴 설정 .editorconfig:7
insert_final_newlinetrue.editorconfig:6 [*]
tab_width4vendor/.editorconfig:3 [*]
trim_trailing_whitespacefalsevendor/.editorconfig:4 [*]
발견된 문제

각 줄은 파일이 보이는 것과 다르게 동작하는 지점입니다.

  • .editorconfig:13 — 중괄호 안의 공백은 일치 대상 문자열의 일부입니다: [*.{md, txt}]

editorconfig-core와 같은 방식으로 해석하며 섹션 이름은 대소문자를 구분합니다. 업로드는 없습니다.

사용법

  1. 첫 번째 상자에 .editorconfig를 붙여넣습니다. 파일이 여러 개면 "# path: vendor/.editorconfig" 같은 표시 줄로 각각을 구분하고, 프로젝트 루트 파일을 맨 앞에 둡니다.
  2. 두 번째 상자에 검사할 경로를 한 줄에 하나씩 적습니다. 최상위 .editorconfig가 있는 프로젝트 루트 기준의 상대 경로입니다.
  3. 경로별 표를 읽습니다. 속성, 최종 값, 그리고 그 값을 정한 파일·줄·섹션 글롭이 나옵니다. 유도됨으로 표시된 줄은 어느 파일에도 적혀 있지 않은 값이며, 어떤 규칙에서 나왔는지 함께 표시됩니다.
  4. 표 위의 탐색 경로 줄을 확인합니다. 가까운 순서로 참조한 .editorconfig 목록과, root = true가 탐색을 멈췄는지 아니면 프로젝트 위로 계속 올라가는지가 나옵니다.
  5. 발견 패널을 차례로 확인합니다. 죽은 섹션, 절대 이기지 못하는 설정, 중괄호 안의 공백처럼 파일이 보이는 것과 다르게 동작하는 지점을 파일과 줄 번호로 짚어 줍니다.

자주 묻는 질문

[*]에 2라고 썼는데 왜 공백 네 칸이 되나요?
뒤에 있거나 더 가까운 설정이 이겼기 때문입니다. EditorConfig에는 CSS 같은 구체성 순위가 없습니다. 한 파일 안에서는 마지막에 일치한 섹션이 이기므로, [*] 블록 스무 줄 아래의 [*.py] 블록이 조용히 덮어씁니다. 같은 이름의 [*] 섹션이 아래에 한 번 더 나와도 마찬가지여서 섹션 이름 중복이 문제가 됩니다. 파일끼리는 속성별로 가장 가까운 .editorconfig가 이기므로, 작업 중인 디렉터리의 두 줄짜리 파일이 루트의 잘 정리된 파일을 이깁니다. 순서와 거리가 전부이며, "설정한 곳" 열이 값을 만든 파일과 줄과 섹션 글롭, 그리고 그것이 밀어낸 설정까지 보여 줍니다.
[*.js], [lib/*.js], [**/*.js]는 무엇이 다른가요?
차이는 슬래시의 유무뿐입니다. 슬래시가 없는 글롭은 깊이와 상관없이 파일 이름만 보므로 [*.js]는 src/a.js도 vendor/dist/b.js도 포함합니다. 끝이 아닌 자리에 슬래시가 하나라도 있으면 그 .editorconfig가 있는 디렉터리에 고정되어, [lib/*.js]는 lib/a.js에만 맞고 lib/sub/a.js에도 src/lib/a.js에도 맞지 않습니다. [**/*.js]는 고정되어 있으면서 디렉터리를 넘나드는 형태입니다. *는 슬래시에서 멈추지만 **는 넘어가고, 가운데의 /**/는 디렉터리가 아예 없는 경우도 뜻하므로 a.js와 lib/sub/a.js가 모두 맞습니다. 마지막 함정으로 [lib/]처럼 슬래시로 끝나는 글롭은 아무것도 맞히지 못합니다. 파일 경로는 슬래시로 끝나지 않기 때문이며, 하위 전체는 [lib/**]로 씁니다.
쓴 적 없는 indent_size = tab과 tab_width는 어디서 왔나요?
병합이 끝난 뒤 코어가 적용하는 대체 규칙에서 나옵니다. indent_style이 tab이고 indent_size가 없으면 indent_size는 tab이 됩니다. indent_size가 숫자이고 tab_width가 없으면 tab_width가 그 값을 복사하므로, indent_size만 적은 파일에서도 tab_width가 함께 보고됩니다. 반대로 indent_size가 tab이고 tab_width가 있으면 indent_size가 그 숫자를 가져옵니다. 병합 결과에 대해 동작하기 때문에 두 조각이 서로 다른 파일에서 올 수 있습니다. unset도 같은 경로를 타므로 indent_size = unset이면 tab_width까지 unset이 됩니다.
root = true는 정확히 무엇을 멈추나요?
.editorconfig를 더 찾으러 위로 올라가는 탐색을 멈춥니다. 이 줄이 없으면 탐색은 프로젝트에서 끝나지 않고 상위 디렉터리, 홈 디렉터리, 파일 시스템 루트까지 계속되며 거기서 찾은 설정이 내 파일이 정하지 않은 속성을 채웁니다. 두 가지가 중요합니다. 첫 섹션 헤더보다 위, 즉 서두에 있어야 합니다. [*] 블록 안에 쓰면 root라는 이름의 평범한 속성일 뿐이라 아무것도 멈추지 않습니다. 또한 그 파일의 섹션이 하나도 맞지 않아도 root = true는 읽히므로, 섹션이 전부 어긋난 설정 파일도 탐색을 끝냅니다.
[*.{js, ts}]가 왜 .ts 파일에 적용되지 않나요?
공백이 패턴의 일부이기 때문입니다. 중괄호 선택지는 쉼표 사이 문자열을 그대로 비교하며 섹션 헤더에서는 어떤 공백도 다듬지 않습니다. 따라서 {js, ts}가 제시하는 후보는 "js"와 " ts"이고, 이름에 실제로 공백이 들어간 파일만 두 번째 후보에 맞습니다. 비슷한 함정이 둘 더 있습니다. 쉼표가 없는 {js}는 선택지가 아니라 문자 그대로 {js} 세 글자라서 [*.{js}]는 app.{js}라는 이름의 파일에만 적용됩니다. 그리고 {1..10} 같은 숫자 범위는 앞자리 0을 거부하므로 1.txt와 10.txt는 맞지만 01.txt는 맞지 않습니다.
역슬래시로 별표를 이스케이프할 수 있나요?
설명서 문구와 달리 참조 구현에서는 되지 않습니다. 코어는 글롭을 한 번에 정규식으로 옮기는데, 이스케이프가 실제로 처리되는 문자는 쉼표, 닫는 중괄호, #, ; 뿐입니다. 이들은 그대로 두면 패턴을 끝내거나 선택지를 나누는 문자입니다. 별표나 물음표 앞의 역슬래시는 버려지고 와일드카드는 그대로 남아서 [a\*b.txt]는 aXb.txt에도 맞습니다. 더 나쁜 경우로 \[와 \{는 생성된 정규식의 괄호 짝을 깨뜨려 컴파일 자체가 실패하고, 편집기 플러그인은 대개 아무 말 없이 .editorconfig 전체를 무시합니다. 이 도구는 추측하지 않고 그대로 재현해 해당 섹션을 사용할 수 없는 글롭으로 표시합니다. 실무적인 조언은 섹션 이름에 중괄호와 대괄호, 별표를 넣지 않는 것입니다.

관련 도구