Add a foldable indicator for multi-line comments

This commit is contained in:
Nathan Sobo 2014-01-18 12:08:37 -07:00
parent 4db2ad53fd
commit ed93695d64
3 changed files with 39 additions and 8 deletions

View File

@ -15,6 +15,6 @@ var quicksort = function () {
}
return sort(left).concat(pivot).concat(sort(right));
};
// this is a single-line comment
return sort(Array.apply(this, arguments));
};

View File

@ -106,7 +106,6 @@ describe "LanguageMode", ->
range = languageMode.rowRangeForParagraphAtBufferRow(15)
expect(range).toEqual [[15,0], [15,26]]
describe "coffeescript", ->
beforeEach ->
atom.packages.activatePackage('language-coffee-script', sync: true)
@ -297,6 +296,14 @@ describe "LanguageMode", ->
languageMode.unfoldBufferRow(1)
expect(editor.lineForScreenRow(1).fold).toBeUndefined()
describe ".isFoldableAtBufferRow(bufferRow)", ->
it "returns true if the line starts a foldable row range", ->
expect(languageMode.isFoldableAtBufferRow(0)).toBe true
expect(languageMode.isFoldableAtBufferRow(1)).toBe true
expect(languageMode.isFoldableAtBufferRow(2)).toBe false
expect(languageMode.isFoldableAtBufferRow(3)).toBe false
expect(languageMode.isFoldableAtBufferRow(4)).toBe true
describe "folding with comments", ->
beforeEach ->
atom.packages.activatePackage('language-javascript', sync: true)
@ -350,6 +357,12 @@ describe "LanguageMode", ->
fold2 = editor.lineForScreenRow(5).fold
expect(fold2).toBeFalsy()
describe ".isFoldableAtBufferRow(bufferRow)", ->
it "returns true if the line starts a multi-line comment", ->
expect(languageMode.isFoldableAtBufferRow(1)).toBe true
expect(languageMode.isFoldableAtBufferRow(6)).toBe true
expect(languageMode.isFoldableAtBufferRow(17)).toBe false
describe "css", ->
beforeEach ->
atom.packages.activatePackage('language-source', sync: true)

View File

@ -178,22 +178,40 @@ class LanguageMode
[bufferRow, foldEndRow]
# Public: Returns a {Boolean} indicating whether the given buffer row starts a
# foldable row range. Rows that are "foldable" have a fold icon next to their
# icon in the gutter in the default configuration.
isFoldableAtBufferRow: (bufferRow) ->
@isFoldableCodeAtBufferRow(bufferRow) or @isFoldableCommentAtBufferRow(bufferRow)
# Private: Returns a {Boolean} indicating whether the given buffer row starts
# a a foldable row range due to the code's indentation patterns.
isFoldableCodeAtBufferRow: (bufferRow) ->
return false if @editor.isBufferRowBlank(bufferRow)
nextNonEmptyRow = @editor.nextNonBlankBufferRow(bufferRow)
return false unless nextNonEmptyRow?
@editor.indentationForBufferRow(nextNonEmptyRow) > @editor.indentationForBufferRow(bufferRow)
# Private: Returns a {Boolean} indicating whether the given buffer row starts
# a foldable row range due to a being the start of a multi-line comment.
isFoldableCommentAtBufferRow: (bufferRow) ->
@isLineCommentedAtBufferRow(bufferRow) and
@isLineCommentedAtBufferRow(bufferRow + 1) and
not @isLineCommentedAtBufferRow(bufferRow - 1)
# Private: Returns a {Boolean} indicating whether the line at the given buffer
# row is a comment.
isLineCommentedAtBufferRow: (bufferRow) ->
return false unless 0 <= bufferRow <= @editor.getLastBufferRow()
@editor.displayBuffer.tokenizedBuffer.lineForScreenRow(bufferRow).isComment()
# Find a row range for a 'paragraph' around specified bufferRow.
# Right now, a paragraph is a block of text bounded by and empty line or a
# block of text that is not the same type (comments next to source code).
rowRangeForParagraphAtBufferRow: (bufferRow) ->
return unless /\w/.test(@editor.lineForBufferRow(bufferRow))
isRowComment = (row) =>
@editor.displayBuffer.tokenizedBuffer.lineForScreenRow(row).isComment()
if isRowComment(bufferRow)
if @isLineCommentedAtBufferRow(bufferRow)
isOriginalRowComment = true
range = @rowRangeForCommentAtBufferRow(bufferRow)
[firstRow, lastRow] = range or [bufferRow, bufferRow]
@ -203,14 +221,14 @@ class LanguageMode
startRow = bufferRow
while startRow > firstRow
break if isRowComment(startRow - 1) != isOriginalRowComment
break if @isLineCommentedAtBufferRow(startRow - 1) != isOriginalRowComment
break unless /\w/.test(@editor.lineForBufferRow(startRow - 1))
startRow--
endRow = bufferRow
lastRow = @editor.getLastBufferRow()
while endRow < lastRow
break if isRowComment(endRow + 1) != isOriginalRowComment
break if @isLineCommentedAtBufferRow(endRow + 1) != isOriginalRowComment
break unless /\w/.test(@editor.lineForBufferRow(endRow + 1))
endRow++