mirror of
https://github.com/atom/atom.git
synced 2026-01-23 22:08:08 -05:00
Fix toggleLineCommentsForBufferRows
This commit is contained in:
@@ -5,6 +5,7 @@ const {Point, Range} = TextBuffer
|
||||
const _ = require('underscore-plus')
|
||||
const dedent = require('dedent')
|
||||
const {it, fit, ffit, fffit, beforeEach, afterEach} = require('./async-spec-helpers')
|
||||
const {ScopedSettingsDelegate} = require('../src/text-editor-registry')
|
||||
|
||||
describe('TokenizedBuffer', () => {
|
||||
let tokenizedBuffer, buffer
|
||||
@@ -16,7 +17,10 @@ describe('TokenizedBuffer', () => {
|
||||
await atom.packages.activatePackage('language-javascript')
|
||||
})
|
||||
|
||||
afterEach(() => tokenizedBuffer && tokenizedBuffer.destroy())
|
||||
afterEach(() => {
|
||||
buffer && buffer.destroy()
|
||||
tokenizedBuffer && tokenizedBuffer.destroy()
|
||||
})
|
||||
|
||||
function startTokenizing (tokenizedBuffer) {
|
||||
tokenizedBuffer.setVisible(true)
|
||||
@@ -640,159 +644,181 @@ describe('TokenizedBuffer', () => {
|
||||
})
|
||||
|
||||
describe('.toggleLineCommentsForBufferRows', () => {
|
||||
let editor
|
||||
|
||||
describe('xml', () => {
|
||||
beforeEach(async () => {
|
||||
editor = await atom.workspace.open('sample.xml', {autoIndent: false})
|
||||
editor.setText('<!-- test -->')
|
||||
await atom.packages.activatePackage('language-xml')
|
||||
buffer = new TextBuffer('<!-- test -->')
|
||||
tokenizedBuffer = new TokenizedBuffer({
|
||||
buffer,
|
||||
grammar: atom.grammars.grammarForScopeName('text.xml'),
|
||||
scopedSettingsDelegate: new ScopedSettingsDelegate(atom.config)
|
||||
})
|
||||
})
|
||||
|
||||
it('removes the leading whitespace from the comment end pattern match when uncommenting lines', () => {
|
||||
editor.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(editor.lineTextForBufferRow(0)).toBe('test')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(buffer.lineForRow(0)).toBe('test')
|
||||
})
|
||||
})
|
||||
|
||||
describe('less', () => {
|
||||
beforeEach(async () => {
|
||||
editor = await atom.workspace.open('sample.less', {autoIndent: false})
|
||||
await atom.packages.activatePackage('language-less')
|
||||
await atom.packages.activatePackage('language-css')
|
||||
buffer = await TextBuffer.load(require.resolve('./fixtures/sample.less'))
|
||||
tokenizedBuffer = new TokenizedBuffer({
|
||||
buffer,
|
||||
grammar: atom.grammars.grammarForScopeName('source.css.less'),
|
||||
scopedSettingsDelegate: new ScopedSettingsDelegate(atom.config)
|
||||
})
|
||||
})
|
||||
|
||||
it('only uses the `commentEnd` pattern if it comes from the same grammar as the `commentStart` when commenting lines', () => {
|
||||
editor.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(editor.lineTextForBufferRow(0)).toBe('// @color: #4D926F;')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(buffer.lineForRow(0)).toBe('// @color: #4D926F;')
|
||||
})
|
||||
})
|
||||
|
||||
describe('css', () => {
|
||||
beforeEach(async () => {
|
||||
editor = await atom.workspace.open('css.css', {autoIndent: false})
|
||||
await atom.packages.activatePackage('language-css')
|
||||
buffer = await TextBuffer.load(require.resolve('./fixtures/css.css'))
|
||||
tokenizedBuffer = new TokenizedBuffer({
|
||||
buffer,
|
||||
grammar: atom.grammars.grammarForScopeName('source.css'),
|
||||
scopedSettingsDelegate: new ScopedSettingsDelegate(atom.config)
|
||||
})
|
||||
})
|
||||
|
||||
it('comments/uncomments lines in the given range', () => {
|
||||
editor.toggleLineCommentsForBufferRows(0, 1)
|
||||
expect(editor.lineTextForBufferRow(0)).toBe('/*body {')
|
||||
expect(editor.lineTextForBufferRow(1)).toBe(' font-size: 1234px;*/')
|
||||
expect(editor.lineTextForBufferRow(2)).toBe(' width: 110%;')
|
||||
expect(editor.lineTextForBufferRow(3)).toBe(' font-weight: bold !important;')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(0, 1)
|
||||
expect(buffer.lineForRow(0)).toBe('/*body {')
|
||||
expect(buffer.lineForRow(1)).toBe(' font-size: 1234px;*/')
|
||||
expect(buffer.lineForRow(2)).toBe(' width: 110%;')
|
||||
expect(buffer.lineForRow(3)).toBe(' font-weight: bold !important;')
|
||||
|
||||
editor.toggleLineCommentsForBufferRows(2, 2)
|
||||
expect(editor.lineTextForBufferRow(0)).toBe('/*body {')
|
||||
expect(editor.lineTextForBufferRow(1)).toBe(' font-size: 1234px;*/')
|
||||
expect(editor.lineTextForBufferRow(2)).toBe(' /*width: 110%;*/')
|
||||
expect(editor.lineTextForBufferRow(3)).toBe(' font-weight: bold !important;')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(2, 2)
|
||||
expect(buffer.lineForRow(0)).toBe('/*body {')
|
||||
expect(buffer.lineForRow(1)).toBe(' font-size: 1234px;*/')
|
||||
expect(buffer.lineForRow(2)).toBe(' /*width: 110%;*/')
|
||||
expect(buffer.lineForRow(3)).toBe(' font-weight: bold !important;')
|
||||
|
||||
editor.toggleLineCommentsForBufferRows(0, 1)
|
||||
expect(editor.lineTextForBufferRow(0)).toBe('body {')
|
||||
expect(editor.lineTextForBufferRow(1)).toBe(' font-size: 1234px;')
|
||||
expect(editor.lineTextForBufferRow(2)).toBe(' /*width: 110%;*/')
|
||||
expect(editor.lineTextForBufferRow(3)).toBe(' font-weight: bold !important;')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(0, 1)
|
||||
expect(buffer.lineForRow(0)).toBe('body {')
|
||||
expect(buffer.lineForRow(1)).toBe(' font-size: 1234px;')
|
||||
expect(buffer.lineForRow(2)).toBe(' /*width: 110%;*/')
|
||||
expect(buffer.lineForRow(3)).toBe(' font-weight: bold !important;')
|
||||
})
|
||||
|
||||
it('uncomments lines with leading whitespace', () => {
|
||||
editor.setTextInBufferRange([[2, 0], [2, Infinity]], ' /*width: 110%;*/')
|
||||
editor.toggleLineCommentsForBufferRows(2, 2)
|
||||
expect(editor.lineTextForBufferRow(2)).toBe(' width: 110%;')
|
||||
buffer.setTextInRange([[2, 0], [2, Infinity]], ' /*width: 110%;*/')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(2, 2)
|
||||
expect(buffer.lineForRow(2)).toBe(' width: 110%;')
|
||||
})
|
||||
|
||||
it('uncomments lines with trailing whitespace', () => {
|
||||
editor.setTextInBufferRange([[2, 0], [2, Infinity]], '/*width: 110%;*/ ')
|
||||
editor.toggleLineCommentsForBufferRows(2, 2)
|
||||
expect(editor.lineTextForBufferRow(2)).toBe('width: 110%; ')
|
||||
buffer.setTextInRange([[2, 0], [2, Infinity]], '/*width: 110%;*/ ')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(2, 2)
|
||||
expect(buffer.lineForRow(2)).toBe('width: 110%; ')
|
||||
})
|
||||
|
||||
it('uncomments lines with leading and trailing whitespace', () => {
|
||||
editor.setTextInBufferRange([[2, 0], [2, Infinity]], ' /*width: 110%;*/ ')
|
||||
editor.toggleLineCommentsForBufferRows(2, 2)
|
||||
expect(editor.lineTextForBufferRow(2)).toBe(' width: 110%; ')
|
||||
buffer.setTextInRange([[2, 0], [2, Infinity]], ' /*width: 110%;*/ ')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(2, 2)
|
||||
expect(buffer.lineForRow(2)).toBe(' width: 110%; ')
|
||||
})
|
||||
})
|
||||
|
||||
describe('coffeescript', () => {
|
||||
beforeEach(async () => {
|
||||
editor = await atom.workspace.open('coffee.coffee', {autoIndent: false})
|
||||
await atom.packages.activatePackage('language-coffee-script')
|
||||
buffer = await TextBuffer.load(require.resolve('./fixtures/coffee.coffee'))
|
||||
tokenizedBuffer = new TokenizedBuffer({
|
||||
buffer,
|
||||
tabLength: 2,
|
||||
grammar: atom.grammars.grammarForScopeName('source.coffee'),
|
||||
scopedSettingsDelegate: new ScopedSettingsDelegate(atom.config)
|
||||
})
|
||||
})
|
||||
|
||||
it('comments/uncomments lines in the given range', () => {
|
||||
editor.toggleLineCommentsForBufferRows(4, 6)
|
||||
expect(editor.lineTextForBufferRow(4)).toBe(' # pivot = items.shift()')
|
||||
expect(editor.lineTextForBufferRow(5)).toBe(' # left = []')
|
||||
expect(editor.lineTextForBufferRow(6)).toBe(' # right = []')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(4, 6)
|
||||
expect(buffer.lineForRow(4)).toBe(' # pivot = items.shift()')
|
||||
expect(buffer.lineForRow(5)).toBe(' # left = []')
|
||||
expect(buffer.lineForRow(6)).toBe(' # right = []')
|
||||
|
||||
editor.toggleLineCommentsForBufferRows(4, 5)
|
||||
expect(editor.lineTextForBufferRow(4)).toBe(' pivot = items.shift()')
|
||||
expect(editor.lineTextForBufferRow(5)).toBe(' left = []')
|
||||
expect(editor.lineTextForBufferRow(6)).toBe(' # right = []')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(4, 5)
|
||||
expect(buffer.lineForRow(4)).toBe(' pivot = items.shift()')
|
||||
expect(buffer.lineForRow(5)).toBe(' left = []')
|
||||
expect(buffer.lineForRow(6)).toBe(' # right = []')
|
||||
})
|
||||
|
||||
it('comments/uncomments empty lines', () => {
|
||||
editor.toggleLineCommentsForBufferRows(4, 7)
|
||||
expect(editor.lineTextForBufferRow(4)).toBe(' # pivot = items.shift()')
|
||||
expect(editor.lineTextForBufferRow(5)).toBe(' # left = []')
|
||||
expect(editor.lineTextForBufferRow(6)).toBe(' # right = []')
|
||||
expect(editor.lineTextForBufferRow(7)).toBe(' # ')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(4, 7)
|
||||
expect(buffer.lineForRow(4)).toBe(' # pivot = items.shift()')
|
||||
expect(buffer.lineForRow(5)).toBe(' # left = []')
|
||||
expect(buffer.lineForRow(6)).toBe(' # right = []')
|
||||
expect(buffer.lineForRow(7)).toBe(' # ')
|
||||
|
||||
editor.toggleLineCommentsForBufferRows(4, 5)
|
||||
expect(editor.lineTextForBufferRow(4)).toBe(' pivot = items.shift()')
|
||||
expect(editor.lineTextForBufferRow(5)).toBe(' left = []')
|
||||
expect(editor.lineTextForBufferRow(6)).toBe(' # right = []')
|
||||
expect(editor.lineTextForBufferRow(7)).toBe(' # ')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(4, 5)
|
||||
expect(buffer.lineForRow(4)).toBe(' pivot = items.shift()')
|
||||
expect(buffer.lineForRow(5)).toBe(' left = []')
|
||||
expect(buffer.lineForRow(6)).toBe(' # right = []')
|
||||
expect(buffer.lineForRow(7)).toBe(' # ')
|
||||
})
|
||||
})
|
||||
|
||||
describe('javascript', () => {
|
||||
beforeEach(async () => {
|
||||
editor = await atom.workspace.open('sample.js', {autoIndent: false})
|
||||
await atom.packages.activatePackage('language-javascript')
|
||||
buffer = await TextBuffer.load(require.resolve('./fixtures/sample.js'))
|
||||
tokenizedBuffer = new TokenizedBuffer({
|
||||
buffer,
|
||||
tabLength: 2,
|
||||
grammar: atom.grammars.grammarForScopeName('source.js'),
|
||||
scopedSettingsDelegate: new ScopedSettingsDelegate(atom.config)
|
||||
})
|
||||
})
|
||||
|
||||
it('comments/uncomments lines in the given range', () => {
|
||||
editor.toggleLineCommentsForBufferRows(4, 7)
|
||||
expect(editor.lineTextForBufferRow(4)).toBe(' // while(items.length > 0) {')
|
||||
expect(editor.lineTextForBufferRow(5)).toBe(' // current = items.shift();')
|
||||
expect(editor.lineTextForBufferRow(6)).toBe(' // current < pivot ? left.push(current) : right.push(current);')
|
||||
expect(editor.lineTextForBufferRow(7)).toBe(' // }')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(4, 7)
|
||||
expect(buffer.lineForRow(4)).toBe(' // while(items.length > 0) {')
|
||||
expect(buffer.lineForRow(5)).toBe(' // current = items.shift();')
|
||||
expect(buffer.lineForRow(6)).toBe(' // current < pivot ? left.push(current) : right.push(current);')
|
||||
expect(buffer.lineForRow(7)).toBe(' // }')
|
||||
|
||||
editor.toggleLineCommentsForBufferRows(4, 5)
|
||||
expect(editor.lineTextForBufferRow(4)).toBe(' while(items.length > 0) {')
|
||||
expect(editor.lineTextForBufferRow(5)).toBe(' current = items.shift();')
|
||||
console.log(JSON.stringify(editor.lineTextForBufferRow(5)));
|
||||
return
|
||||
expect(editor.lineTextForBufferRow(6)).toBe(' // current < pivot ? left.push(current) : right.push(current);')
|
||||
expect(editor.lineTextForBufferRow(7)).toBe(' // }')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(4, 5)
|
||||
expect(buffer.lineForRow(4)).toBe(' while(items.length > 0) {')
|
||||
expect(buffer.lineForRow(5)).toBe(' current = items.shift();')
|
||||
expect(buffer.lineForRow(6)).toBe(' // current < pivot ? left.push(current) : right.push(current);')
|
||||
expect(buffer.lineForRow(7)).toBe(' // }')
|
||||
|
||||
editor.setText('\tvar i;')
|
||||
editor.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(editor.lineTextForBufferRow(0)).toBe('\t// var i;')
|
||||
buffer.setText('\tvar i;')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(buffer.lineForRow(0)).toBe('\t// var i;')
|
||||
|
||||
editor.setText('var i;')
|
||||
editor.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(editor.lineTextForBufferRow(0)).toBe('// var i;')
|
||||
buffer.setText('var i;')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(buffer.lineForRow(0)).toBe('// var i;')
|
||||
|
||||
editor.setText(' var i;')
|
||||
editor.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(editor.lineTextForBufferRow(0)).toBe(' // var i;')
|
||||
buffer.setText(' var i;')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(buffer.lineForRow(0)).toBe(' // var i;')
|
||||
|
||||
editor.setText(' ')
|
||||
editor.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(editor.lineTextForBufferRow(0)).toBe(' // ')
|
||||
buffer.setText(' ')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(buffer.lineForRow(0)).toBe('// ')
|
||||
|
||||
editor.setText(' a\n \n b')
|
||||
editor.toggleLineCommentsForBufferRows(0, 2)
|
||||
expect(editor.lineTextForBufferRow(0)).toBe(' // a')
|
||||
expect(editor.lineTextForBufferRow(1)).toBe(' // ')
|
||||
expect(editor.lineTextForBufferRow(2)).toBe(' // b')
|
||||
buffer.setText(' a\n \n b')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(0, 2)
|
||||
expect(buffer.lineForRow(0)).toBe(' // a')
|
||||
expect(buffer.lineForRow(1)).toBe(' // ')
|
||||
expect(buffer.lineForRow(2)).toBe(' // b')
|
||||
|
||||
editor.setText(' \n // var i;')
|
||||
editor.toggleLineCommentsForBufferRows(0, 1)
|
||||
expect(editor.lineTextForBufferRow(0)).toBe(' ')
|
||||
expect(editor.lineTextForBufferRow(1)).toBe(' var i;')
|
||||
buffer.setText(' \n // var i;')
|
||||
tokenizedBuffer.toggleLineCommentsForBufferRows(0, 1)
|
||||
expect(buffer.lineForRow(0)).toBe(' ')
|
||||
expect(buffer.lineForRow(1)).toBe(' var i;')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -429,3 +429,5 @@ class ScopedSettingsDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextEditorRegistry.ScopedSettingsDelegate = ScopedSettingsDelegate
|
||||
|
||||
@@ -38,6 +38,7 @@ class TokenizedBuffer {
|
||||
this.tabLength = params.tabLength
|
||||
this.largeFileMode = params.largeFileMode
|
||||
this.assert = params.assert
|
||||
this.scopedSettingsDelegate = params.scopedSettingsDelegate
|
||||
|
||||
this.setGrammar(params.grammar || NullGrammar)
|
||||
this.disposables.add(this.buffer.registerTextDecorationLayer(this))
|
||||
@@ -220,26 +221,28 @@ class TokenizedBuffer {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const indents = []
|
||||
let minIndentLevel = null
|
||||
for (let row = start; row <= end; row++) {
|
||||
const line = this.buffer.lineForRow(row)
|
||||
if (NON_WHITESPACE_REGEX.test(line)) {
|
||||
indents.push(this.indentLevelForLine(line))
|
||||
const indentLevel = this.indentLevelForLine(line)
|
||||
if (minIndentLevel == null || indentLevel < minIndentLevel) minIndentLevel = indentLevel
|
||||
}
|
||||
}
|
||||
if (indents.length === 0) indents.push(0)
|
||||
const indent = Math.min(...indents)
|
||||
if (minIndentLevel == null) minIndentLevel = 0
|
||||
|
||||
const tabLength = this.getTabLength()
|
||||
const indentString = ' '.repeat(tabLength * indent)
|
||||
const indentRegex = new RegExp(`(\t|[ ]{${tabLength}}){${Math.floor(indent)}}`)
|
||||
const indentString = ' '.repeat(tabLength * minIndentLevel)
|
||||
for (let row = start; row <= end; row++) {
|
||||
const line = this.buffer.lineForRow(row)
|
||||
const indentMatch = line.match(indentRegex)
|
||||
if (indentMatch) {
|
||||
this.buffer.insert([row, indentMatch[0].length], commentStartString)
|
||||
if (NON_WHITESPACE_REGEX.test(line)) {
|
||||
const indentColumn = this.columnForIndentLevel(line, minIndentLevel)
|
||||
this.buffer.insert(Point(row, indentColumn), commentStartString)
|
||||
} else {
|
||||
this.buffer.insert([row, 0], indentString + commentStartString)
|
||||
this.buffer.setTextInRange(
|
||||
new Range(new Point(row, 0), new Point(row, Infinity)),
|
||||
indentString + commentStartString
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -581,6 +584,24 @@ class TokenizedBuffer {
|
||||
return scopes
|
||||
}
|
||||
|
||||
columnForIndentLevel (line, indentLevel, tabLength = this.tabLength) {
|
||||
let column = 0
|
||||
let indentLength = 0
|
||||
const goalIndentLength = indentLevel * tabLength
|
||||
while (indentLength < goalIndentLength) {
|
||||
const char = line[column]
|
||||
if (char === '\t') {
|
||||
indentLength += tabLength - (indentLength % tabLength)
|
||||
} else if (char === ' ') {
|
||||
indentLength++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
column++
|
||||
}
|
||||
return column
|
||||
}
|
||||
|
||||
indentLevelForLine (line, tabLength = this.tabLength) {
|
||||
let indentLength = 0
|
||||
for (let i = 0, {length} = line; i < length; i++) {
|
||||
|
||||
Reference in New Issue
Block a user