diff --git a/spec/text-mate-language-mode-spec.js b/spec/text-mate-language-mode-spec.js index 77a54dcd92..fca5e34481 100644 --- a/spec/text-mate-language-mode-spec.js +++ b/spec/text-mate-language-mode-spec.js @@ -51,6 +51,48 @@ describe('TextMateLanguageMode', () => { }); }); + describe('editor.largeFileThreshold config', () => { + afterEach(() => { + config.unset('editor.largeFileThreshold'); + }); + + it('uses the configured threshold to determine large file mode', () => { + config.set('editor.largeFileThreshold', 0.001); // 1KB + const line = 'a b c d\n'; + buffer = new TextBuffer(line.repeat(200)); // ~1.6KB + languageMode = new TextMateLanguageMode({ + buffer, + config, + grammar: atom.grammars.grammarForScopeName('source.js') + }); + expect(languageMode.largeFileMode).toBe(true); + }); + + it('disables automatic large file mode when threshold is 0', () => { + config.set('editor.largeFileThreshold', 0); + const line = 'a b c d\n'; + buffer = new TextBuffer(line.repeat(256 * 1024)); // 2MB + languageMode = new TextMateLanguageMode({ + buffer, + config, + grammar: atom.grammars.grammarForScopeName('source.js') + }); + expect(languageMode.largeFileMode).toBe(false); + }); + + it('respects explicit largeFileMode param over config', () => { + config.set('editor.largeFileThreshold', 0); + buffer = new TextBuffer('small file'); + languageMode = new TextMateLanguageMode({ + buffer, + config, + grammar: atom.grammars.grammarForScopeName('source.js'), + largeFileMode: true + }); + expect(languageMode.largeFileMode).toBe(true); + }); + }); + describe('tokenizing', () => { describe('when the buffer is destroyed', () => { beforeEach(() => { diff --git a/src/config-schema.js b/src/config-schema.js index 39086ee639..68fe74f933 100644 --- a/src/config-schema.js +++ b/src/config-schema.js @@ -455,6 +455,13 @@ const configSchema = { type: ['string', 'null'] }, // These can be used as globals or scoped, thus defaults. + largeFileThreshold: { + description: + 'Files larger than this size in megabytes will open in large file mode with syntax highlighting disabled. Only applies to TextMate grammars; Tree-sitter grammars handle large files efficiently without this limitation. Set to 0 to always enable syntax highlighting regardless of file size.', + type: 'number', + default: 2, + minimum: 0 + }, fontFamily: { type: 'string', default: 'Menlo, Consolas, DejaVu Sans Mono, monospace', diff --git a/src/text-mate-language-mode.js b/src/text-mate-language-mode.js index 54bec84c91..9aaab617c5 100644 --- a/src/text-mate-language-mode.js +++ b/src/text-mate-language-mode.js @@ -29,17 +29,16 @@ class TextMateLanguageMode { this.tokenizationStarted = false; this.id = params.id != null ? params.id : nextId++; this.buffer = params.buffer; - this.largeFileMode = params.largeFileMode; this.config = params.config ?? atom.config; - this.largeFileMode = - params.largeFileMode != null - ? params.largeFileMode - : this.buffer.buffer.getLength() >= 2 * 1024 * 1024; - this.grammar = params.grammar || NullGrammar; this.rootScopeDescriptor = new ScopeDescriptor({ scopes: [this.grammar.scopeName] }); + const largeFileThreshold = this.config.get('editor.largeFileThreshold', { scope: this.rootScopeDescriptor }) ?? 2; + this.largeFileMode = + params.largeFileMode != null + ? params.largeFileMode + : largeFileThreshold > 0 && this.buffer.buffer.getLength() >= largeFileThreshold * 1024 * 1024; this.disposables.add( this.grammar.onDidUpdate(() => this.retokenizeLines()) );