mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-10 10:17:11 +03:00
Merge pull request #1441 from atom/ns-fold-indicators
Allow folds to be toggled by clicking icons in the gutter
This commit is contained in:
commit
338168e145
12
package.json
12
package.json
@ -55,19 +55,19 @@
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
},
|
||||
"packageDependencies": {
|
||||
"atom-dark-syntax": "0.10.0",
|
||||
"atom-dark-syntax": "0.11.0",
|
||||
"atom-dark-ui": "0.21.0",
|
||||
"atom-light-syntax": "0.10.0",
|
||||
"atom-light-syntax": "0.11.0",
|
||||
"atom-light-ui": "0.20.0",
|
||||
"base16-tomorrow-dark-theme": "0.8.0",
|
||||
"solarized-dark-syntax": "0.6.0",
|
||||
"solarized-light-syntax": "0.2.0",
|
||||
"base16-tomorrow-dark-theme": "0.9.0",
|
||||
"solarized-dark-syntax": "0.7.0",
|
||||
"solarized-light-syntax": "0.3.0",
|
||||
"archive-view": "0.21.0",
|
||||
"autocomplete": "0.20.0",
|
||||
"autoflow": "0.12.0",
|
||||
"autosave": "0.10.0",
|
||||
"background-tips": "0.5.0",
|
||||
"bookmarks": "0.16.0",
|
||||
"bookmarks": "0.17.0",
|
||||
"bracket-matcher": "0.19.0",
|
||||
"command-logger": "0.10.0",
|
||||
"command-palette": "0.14.0",
|
||||
|
@ -715,6 +715,14 @@ describe "EditorView", ->
|
||||
expect(selection1.getScreenRange()).toEqual [[4, 10], [5, 27]]
|
||||
expect(selection2.getScreenRange()).toEqual [[6, 10], [8, 27]]
|
||||
|
||||
describe "mousedown on the fold icon of a foldable line number", ->
|
||||
it "toggles folding on the clicked buffer row", ->
|
||||
expect(editor.isFoldedAtScreenRow(1)).toBe false
|
||||
editorView.gutter.find('.line-number:eq(1) .icon-right').mousedown()
|
||||
expect(editor.isFoldedAtScreenRow(1)).toBe true
|
||||
editorView.gutter.find('.line-number:eq(1) .icon-right').mousedown()
|
||||
expect(editor.isFoldedAtScreenRow(1)).toBe false
|
||||
|
||||
describe "when text input events are triggered on the hidden input element", ->
|
||||
it "inserts the typed character at the cursor position, both in the buffer and the pre element", ->
|
||||
editorView.attachToDom()
|
||||
@ -1800,19 +1808,41 @@ describe "EditorView", ->
|
||||
|
||||
it "creates a line number element for each visible line with padding to the left of the number", ->
|
||||
expect(editorView.gutter.find('.line-number').length).toBe 8
|
||||
expect(editorView.find('.line-number:first').html()).toBe " 1"
|
||||
expect(editorView.gutter.find('.line-number:last').html()).toBe " 8"
|
||||
expect(editorView.find('.line-number:first').html()).toMatch /^ 1/
|
||||
expect(editorView.gutter.find('.line-number:last').html()).toMatch /^ 8/
|
||||
|
||||
# here we don't scroll far enough to trigger additional rendering
|
||||
editorView.scrollTop(editorView.lineHeight * 1.5)
|
||||
expect(editorView.renderedLines.find('.line').length).toBe 8
|
||||
expect(editorView.gutter.find('.line-number:first').html()).toBe " 1"
|
||||
expect(editorView.gutter.find('.line-number:last').html()).toBe " 8"
|
||||
expect(editorView.gutter.find('.line-number:first').html()).toMatch /^ 1/
|
||||
expect(editorView.gutter.find('.line-number:last').html()).toMatch /^ 8/
|
||||
|
||||
editorView.scrollTop(editorView.lineHeight * 3.5)
|
||||
expect(editorView.renderedLines.find('.line').length).toBe 10
|
||||
expect(editorView.gutter.find('.line-number:first').html()).toBe " 2"
|
||||
expect(editorView.gutter.find('.line-number:last').html()).toBe "11"
|
||||
expect(editorView.gutter.find('.line-number:first').html()).toMatch /^ 2/
|
||||
expect(editorView.gutter.find('.line-number:last').html()).toMatch /^11/
|
||||
|
||||
it "adds a .foldable class to lines that start foldable regions", ->
|
||||
expect(editorView.gutter.find('.line-number:eq(0)')).toHaveClass 'foldable'
|
||||
expect(editorView.gutter.find('.line-number:eq(1)')).toHaveClass 'foldable'
|
||||
expect(editorView.gutter.find('.line-number:eq(2)')).not.toHaveClass 'foldable'
|
||||
expect(editorView.gutter.find('.line-number:eq(3)')).not.toHaveClass 'foldable'
|
||||
expect(editorView.gutter.find('.line-number:eq(4)')).toHaveClass 'foldable'
|
||||
|
||||
# changes to indentation update foldability
|
||||
editor.setIndentationForBufferRow(1, 0)
|
||||
expect(editorView.gutter.find('.line-number:eq(0)')).not.toHaveClass 'foldable'
|
||||
expect(editorView.gutter.find('.line-number:eq(1)')).toHaveClass 'foldable'
|
||||
|
||||
# changes to comments update foldability
|
||||
editor.toggleLineCommentsForBufferRows(2, 3)
|
||||
expect(editorView.gutter.find('.line-number:eq(2)')).toHaveClass 'foldable'
|
||||
expect(editorView.gutter.find('.line-number:eq(3)')).not.toHaveClass 'foldable'
|
||||
editor.toggleLineCommentForBufferRow(2)
|
||||
expect(editorView.gutter.find('.line-number:eq(2)')).not.toHaveClass 'foldable'
|
||||
expect(editorView.gutter.find('.line-number:eq(3)')).not.toHaveClass 'foldable'
|
||||
editor.toggleLineCommentForBufferRow(4)
|
||||
expect(editorView.gutter.find('.line-number:eq(3)')).toHaveClass 'foldable'
|
||||
|
||||
describe "when lines are inserted", ->
|
||||
it "re-renders the correct line number range in the gutter", ->
|
||||
@ -1827,11 +1857,11 @@ describe "EditorView", ->
|
||||
|
||||
it "re-renders the correct line number range when there are folds", ->
|
||||
editorView.editor.foldBufferRow(1)
|
||||
expect(editorView.gutter.find('.line-number-1')).toHaveClass 'fold'
|
||||
expect(editorView.gutter.find('.line-number-1')).toHaveClass 'folded'
|
||||
|
||||
buffer.insert([0, 0], '\n')
|
||||
|
||||
expect(editorView.gutter.find('.line-number-2')).toHaveClass 'fold'
|
||||
expect(editorView.gutter.find('.line-number-2')).toHaveClass 'folded'
|
||||
|
||||
describe "when wrapping is on", ->
|
||||
it "renders a • instead of line number for wrapped portions of lines", ->
|
||||
@ -1839,7 +1869,7 @@ describe "EditorView", ->
|
||||
editorView.setWidthInChars(50)
|
||||
expect(editorView.gutter.find('.line-number').length).toEqual(8)
|
||||
expect(editorView.gutter.find('.line-number:eq(3)').intValue()).toBe 4
|
||||
expect(editorView.gutter.find('.line-number:eq(4)').html()).toBe ' •'
|
||||
expect(editorView.gutter.find('.line-number:eq(4)').html()).toMatch /^ •/
|
||||
expect(editorView.gutter.find('.line-number:eq(5)').intValue()).toBe 5
|
||||
|
||||
describe "when there are folds", ->
|
||||
@ -1866,8 +1896,8 @@ describe "EditorView", ->
|
||||
|
||||
it "styles folded line numbers", ->
|
||||
editor.createFold(3, 5)
|
||||
expect(editorView.gutter.find('.line-number.fold').length).toBe 1
|
||||
expect(editorView.gutter.find('.line-number.fold:eq(0)').intValue()).toBe 4
|
||||
expect(editorView.gutter.find('.line-number.folded').length).toBe 1
|
||||
expect(editorView.gutter.find('.line-number.folded:eq(0)').intValue()).toBe 4
|
||||
|
||||
describe "when the scrollView is scrolled to the right", ->
|
||||
it "adds a drop shadow to the gutter", ->
|
||||
|
2
spec/fixtures/sample-with-comments.js
vendored
2
spec/fixtures/sample-with-comments.js
vendored
@ -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));
|
||||
};
|
@ -44,20 +44,12 @@ describe "LanguageMode", ->
|
||||
languageMode.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(buffer.lineForRow(0)).toBe " // var i;"
|
||||
|
||||
describe "fold suggestion", ->
|
||||
describe ".doesBufferRowStartFold(bufferRow)", ->
|
||||
it "returns true only when the buffer row starts a foldable region", ->
|
||||
expect(languageMode.doesBufferRowStartFold(0)).toBeTruthy()
|
||||
expect(languageMode.doesBufferRowStartFold(1)).toBeTruthy()
|
||||
expect(languageMode.doesBufferRowStartFold(2)).toBeFalsy()
|
||||
expect(languageMode.doesBufferRowStartFold(3)).toBeFalsy()
|
||||
|
||||
describe ".rowRangeForCodeFoldAtBufferRow(bufferRow)", ->
|
||||
it "returns the start/end rows of the foldable region starting at the given row", ->
|
||||
expect(languageMode.rowRangeForCodeFoldAtBufferRow(0)).toEqual [0, 12]
|
||||
expect(languageMode.rowRangeForCodeFoldAtBufferRow(1)).toEqual [1, 9]
|
||||
expect(languageMode.rowRangeForCodeFoldAtBufferRow(2)).toBeNull()
|
||||
expect(languageMode.rowRangeForCodeFoldAtBufferRow(4)).toEqual [4, 7]
|
||||
describe ".rowRangeForCodeFoldAtBufferRow(bufferRow)", ->
|
||||
it "returns the start/end rows of the foldable region starting at the given row", ->
|
||||
expect(languageMode.rowRangeForCodeFoldAtBufferRow(0)).toEqual [0, 12]
|
||||
expect(languageMode.rowRangeForCodeFoldAtBufferRow(1)).toEqual [1, 9]
|
||||
expect(languageMode.rowRangeForCodeFoldAtBufferRow(2)).toBeNull()
|
||||
expect(languageMode.rowRangeForCodeFoldAtBufferRow(4)).toEqual [4, 7]
|
||||
|
||||
describe "suggestedIndentForBufferRow", ->
|
||||
it "returns the suggested indentation based on auto-indent/outdent rules", ->
|
||||
@ -106,7 +98,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)
|
||||
@ -139,13 +130,13 @@ describe "LanguageMode", ->
|
||||
expect(buffer.lineForRow(7)).toBe " # "
|
||||
|
||||
describe "fold suggestion", ->
|
||||
describe ".doesBufferRowStartFold(bufferRow)", ->
|
||||
describe ".isFoldableAtBufferRow(bufferRow)", ->
|
||||
it "returns true only when the buffer row starts a foldable region", ->
|
||||
expect(languageMode.doesBufferRowStartFold(0)).toBeTruthy()
|
||||
expect(languageMode.doesBufferRowStartFold(1)).toBeTruthy()
|
||||
expect(languageMode.doesBufferRowStartFold(2)).toBeFalsy()
|
||||
expect(languageMode.doesBufferRowStartFold(3)).toBeFalsy()
|
||||
expect(languageMode.doesBufferRowStartFold(19)).toBeTruthy()
|
||||
expect(languageMode.isFoldableAtBufferRow(0)).toBeTruthy()
|
||||
expect(languageMode.isFoldableAtBufferRow(1)).toBeTruthy()
|
||||
expect(languageMode.isFoldableAtBufferRow(2)).toBeFalsy()
|
||||
expect(languageMode.isFoldableAtBufferRow(3)).toBeFalsy()
|
||||
expect(languageMode.isFoldableAtBufferRow(19)).toBeTruthy()
|
||||
|
||||
describe ".rowRangeForCodeFoldAtBufferRow(bufferRow)", ->
|
||||
it "returns the start/end rows of the foldable region starting at the given row", ->
|
||||
@ -297,6 +288,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 +349,17 @@ 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
|
||||
|
||||
it "does not return true for a line in the middle of a comment that's followed by an indented line", ->
|
||||
expect(languageMode.isFoldableAtBufferRow(7)).toBe false
|
||||
editor.buffer.insert([8, 0], ' ')
|
||||
expect(languageMode.isFoldableAtBufferRow(7)).toBe false
|
||||
|
||||
describe "css", ->
|
||||
beforeEach ->
|
||||
atom.packages.activatePackage('language-source', sync: true)
|
||||
|
@ -348,6 +348,11 @@ class EditorView extends View
|
||||
@editor.destroyFoldWithId(id)
|
||||
false
|
||||
|
||||
@gutter.on 'mousedown', '.foldable .icon-right', (e) =>
|
||||
bufferRow = $(e.target).parent().data('bufferRow')
|
||||
@editor.toggleFoldAtBufferRow(bufferRow)
|
||||
false
|
||||
|
||||
@renderedLines.on 'mousedown', (e) =>
|
||||
clickCount = e.originalEvent.detail
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
_ = require 'underscore-plus'
|
||||
path = require 'path'
|
||||
Serializable = require 'serializable'
|
||||
Delegator = require 'delegato'
|
||||
{Model} = require 'theorist'
|
||||
{Point, Range} = require 'text-buffer'
|
||||
LanguageMode = require './language-mode'
|
||||
@ -33,6 +34,7 @@ module.exports =
|
||||
class Editor extends Model
|
||||
Serializable.includeInto(this)
|
||||
atom.deserializers.add(this)
|
||||
Delegator.includeInto(this)
|
||||
|
||||
@properties
|
||||
scrollTop: 0
|
||||
@ -47,6 +49,11 @@ class Editor extends Model
|
||||
selections: null
|
||||
suppressSelectionMerging: false
|
||||
|
||||
@delegatesMethods 'foldAll', 'unfoldAll', 'foldAllAtIndentLevel', 'foldBufferRow',
|
||||
'unfoldBufferRow', 'suggestedIndentForBufferRow', 'autoIndentBufferRow', 'autoIndentBufferRows',
|
||||
'autoDecreaseIndentForBufferRow', 'toggleLineCommentForBufferRow', 'toggleLineCommentsForBufferRows',
|
||||
'isFoldableAtBufferRow', toProperty: 'languageMode'
|
||||
|
||||
constructor: ({@softTabs, initialLine, tabLength, softWrap, @displayBuffer, buffer, registerEditor, suppressCursorCreation}) ->
|
||||
super
|
||||
|
||||
@ -560,36 +567,16 @@ class Editor extends Model
|
||||
@getCursor().needsAutoscroll = true
|
||||
@buffer.redo(this)
|
||||
|
||||
# Public: Folds all the rows.
|
||||
foldAll: ->
|
||||
@languageMode.foldAll()
|
||||
|
||||
# Public: Unfolds all the rows.
|
||||
unfoldAll: ->
|
||||
@languageMode.unfoldAll()
|
||||
|
||||
# Public: Creates a fold for each section at the given indent level.
|
||||
foldAllAtIndentLevel: (indentLevel) ->
|
||||
@languageMode.foldAllAtIndentLevel(indentLevel)
|
||||
|
||||
# Public: Folds the current row.
|
||||
foldCurrentRow: ->
|
||||
bufferRow = @bufferPositionForScreenPosition(@getCursorScreenPosition()).row
|
||||
@foldBufferRow(bufferRow)
|
||||
|
||||
# Public: Folds a give buffer row.
|
||||
foldBufferRow: (bufferRow) ->
|
||||
@languageMode.foldBufferRow(bufferRow)
|
||||
|
||||
# Public: Unfolds the current row.
|
||||
unfoldCurrentRow: ->
|
||||
bufferRow = @bufferPositionForScreenPosition(@getCursorScreenPosition()).row
|
||||
@unfoldBufferRow(bufferRow)
|
||||
|
||||
# Public: Unfolds a given a buffer row.
|
||||
unfoldBufferRow: (bufferRow) ->
|
||||
@languageMode.unfoldBufferRow(bufferRow)
|
||||
|
||||
# Public: Folds all selections.
|
||||
foldSelection: ->
|
||||
selection.fold() for selection in @getSelections()
|
||||
@ -611,6 +598,14 @@ class Editor extends Model
|
||||
for row in [bufferRange.start.row..bufferRange.end.row]
|
||||
@destroyFoldsContainingBufferRow(row)
|
||||
|
||||
# Public: Folds the given buffer row if it's not currently folded, and unfolds
|
||||
# it otherwise.
|
||||
toggleFoldAtBufferRow: (bufferRow) ->
|
||||
if @isFoldedAtBufferRow(bufferRow)
|
||||
@unfoldBufferRow(bufferRow)
|
||||
else
|
||||
@foldBufferRow(bufferRow)
|
||||
|
||||
# Public: Returns whether the current row is folded.
|
||||
isFoldedAtCursorRow: ->
|
||||
@isFoldedAtScreenRow(@getCursorScreenRow())
|
||||
@ -631,38 +626,6 @@ class Editor extends Model
|
||||
largestFoldStartingAtScreenRow: (screenRow) ->
|
||||
@displayBuffer.largestFoldStartingAtScreenRow(screenRow)
|
||||
|
||||
# Public: Suggests the indent for the given buffer row.
|
||||
suggestedIndentForBufferRow: (bufferRow) ->
|
||||
@languageMode.suggestedIndentForBufferRow(bufferRow)
|
||||
|
||||
# Public: Indents all the rows between two buffer rows.
|
||||
#
|
||||
# * startRow: The row {Number} to start at (inclusive)
|
||||
# * endRow: The row {Number} to end at (inclusive)
|
||||
autoIndentBufferRows: (startRow, endRow) ->
|
||||
@languageMode.autoIndentBufferRows(startRow, endRow)
|
||||
|
||||
# Public: Indents the given buffer row to it's suggested level.
|
||||
autoIndentBufferRow: (bufferRow) ->
|
||||
@languageMode.autoIndentBufferRow(bufferRow)
|
||||
|
||||
# Public:
|
||||
#
|
||||
# FIXME: What does this do?
|
||||
autoDecreaseIndentForBufferRow: (bufferRow) ->
|
||||
@languageMode.autoDecreaseIndentForBufferRow(bufferRow)
|
||||
|
||||
# Public: Wraps the lines between two rows in comments.
|
||||
#
|
||||
# If the language doesn't have comments, nothing happens.
|
||||
#
|
||||
# startRow - The row {Number} to start at (inclusive)
|
||||
# endRow - The row {Number} to end at (inclusive)
|
||||
#
|
||||
# Returns an {Array} of the commented {Ranges}.
|
||||
toggleLineCommentsForBufferRows: (start, end) ->
|
||||
@languageMode.toggleLineCommentsForBufferRows(start, end)
|
||||
|
||||
# Public: Moves the selected line up one row.
|
||||
moveLineUp: ->
|
||||
selection = @getSelectedBufferRange()
|
||||
|
@ -151,10 +151,12 @@ class Gutter extends View
|
||||
updateAllLines = true
|
||||
break
|
||||
|
||||
# Rebuild the entire gutter if a change added or removed lines
|
||||
if updateAllLines
|
||||
@lineNumbers[0].innerHTML = @buildLineElementsHtml(startScreenRow, endScreenRow)
|
||||
|
||||
# Handle changes that didn't add/remove lines more optimally
|
||||
else
|
||||
# When scrolling or adding/removing lines, we just add/remove lines from the ends.
|
||||
if startScreenRow < @firstScreenRow
|
||||
@prependLineElements(@buildLineElements(startScreenRow, @firstScreenRow-1))
|
||||
else if startScreenRow != @firstScreenRow
|
||||
@ -165,6 +167,8 @@ class Gutter extends View
|
||||
else if endScreenRow != @lastScreenRow
|
||||
@removeLineElements(endScreenRow - @lastScreenRow)
|
||||
|
||||
@updateFoldableClasses(changes)
|
||||
|
||||
@firstScreenRow = startScreenRow
|
||||
@lastScreenRow = endScreenRow
|
||||
@highlightedRows = null
|
||||
@ -202,22 +206,40 @@ class Gutter extends View
|
||||
|
||||
html = ''
|
||||
for row in rows
|
||||
if row == lastScreenRow
|
||||
if row is lastRow
|
||||
rowValue = '•'
|
||||
else
|
||||
rowValue = (row + 1).toString()
|
||||
|
||||
classes = "line-number line-number-#{row}"
|
||||
classes += ' fold' if editor.isFoldedAtBufferRow(row)
|
||||
classes += ' foldable' if row isnt lastRow and editor.isFoldableAtBufferRow(row)
|
||||
classes += ' folded' if editor.isFoldedAtBufferRow(row)
|
||||
|
||||
rowValuePadding = _.multiplyString(' ', maxDigits - rowValue.length)
|
||||
|
||||
html += """<div class="#{classes}">#{rowValuePadding}#{rowValue}</div>"""
|
||||
html += """<div class="#{classes}" data-buffer-row=#{row}>#{rowValuePadding}#{rowValue}<div class="icon-right"></div></div>"""
|
||||
|
||||
lastScreenRow = row
|
||||
lastRow = row
|
||||
|
||||
html
|
||||
|
||||
# Private: Called to update the 'foldable' class of line numbers when there's
|
||||
# a change to the display buffer that doesn't regenerate all the line numbers
|
||||
# anyway.
|
||||
updateFoldableClasses: (changes) ->
|
||||
editor = @getEditor()
|
||||
for {start, end} in changes when start <= @lastScreenRow and end >= @firstScreenRow
|
||||
startScreenRow = Math.max(start - 1, @firstScreenRow)
|
||||
endScreenRow = Math.min(end + 1, @lastScreenRow)
|
||||
lastBufferRow = null
|
||||
for bufferRow in editor.bufferRowsForScreenRows(startScreenRow, endScreenRow) when bufferRow isnt lastBufferRow
|
||||
lastBufferRow = bufferRow
|
||||
lineNumberElement = @getLineNumberElement(bufferRow)[0]
|
||||
if editor.isFoldableAtBufferRow(bufferRow)
|
||||
lineNumberElement.classList.add('foldable')
|
||||
else
|
||||
lineNumberElement.classList.remove('foldable')
|
||||
|
||||
removeLineHighlights: ->
|
||||
return unless @highlightedLineNumbers
|
||||
for line in @highlightedLineNumbers
|
||||
|
@ -28,6 +28,9 @@ class LanguageMode
|
||||
constructor: (@editor) ->
|
||||
@buffer = @editor.buffer
|
||||
|
||||
toggleLineCommentForBufferRow: (row) ->
|
||||
@toggleLineCommentsForBufferRows(row, row)
|
||||
|
||||
# Wraps the lines between two rows in comments.
|
||||
#
|
||||
# If the language doesn't have comment, nothing happens.
|
||||
@ -162,7 +165,7 @@ class LanguageMode
|
||||
return [startRow, endRow] if startRow isnt endRow
|
||||
|
||||
rowRangeForCodeFoldAtBufferRow: (bufferRow) ->
|
||||
return null unless @doesBufferRowStartFold(bufferRow)
|
||||
return null unless @isFoldableAtBufferRow(bufferRow)
|
||||
|
||||
startIndentLevel = @editor.indentationForBufferRow(bufferRow)
|
||||
scopes = @editor.scopesForBufferPosition([bufferRow, 0])
|
||||
@ -178,22 +181,40 @@ class LanguageMode
|
||||
|
||||
[bufferRow, foldEndRow]
|
||||
|
||||
doesBufferRowStartFold: (bufferRow) ->
|
||||
return false if @editor.isBufferRowBlank(bufferRow)
|
||||
# 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) or @isLineCommentedAtBufferRow(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 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 +224,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++
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
}
|
||||
|
||||
.editor .gutter .line-number {
|
||||
padding-right: .5em;
|
||||
padding-left: .5em;
|
||||
opacity: 0.6;
|
||||
position: relative;
|
||||
@ -36,29 +35,48 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.editor .gutter .line-number.fold.cursor-line {
|
||||
.editor .gutter .line-number.folded.cursor-line {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.editor .gutter .line-number.fold:after {
|
||||
visibility: visible;
|
||||
.editor .gutter .line-number .icon-right {
|
||||
.octicon(chevron-down, 0.8em);
|
||||
display: inline-block;
|
||||
visibility: hidden;
|
||||
padding-left: .1em;
|
||||
padding-right: .5em;
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.editor .gutter .line-number:after {
|
||||
.icon(0.8em);
|
||||
content: @chevron-right;
|
||||
opacity: .8;
|
||||
visibility: hidden;
|
||||
position: relative;
|
||||
top: -0.2em;
|
||||
.editor .gutter:hover .line-number.foldable .icon-right {
|
||||
visibility: visible;
|
||||
|
||||
&:before {
|
||||
content: @chevron-down;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.editor .gutter, .editor .gutter:hover {
|
||||
.line-number.folded .icon-right {
|
||||
.octicon(chevron-right, 0.8em);
|
||||
visibility: visible;
|
||||
|
||||
&:before { // chevron-right renders too far right compared to chevron-down
|
||||
position: relative;
|
||||
left: -.1em;
|
||||
content: @chevron-right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.editor .fold-marker:after {
|
||||
.icon(0.8em, inline);
|
||||
content: @ellipsis;
|
||||
padding-left: 0.2em;
|
||||
position: relative;
|
||||
top: -0.2em;
|
||||
}
|
||||
|
||||
.editor .line.cursor-line .fold-marker:after {
|
||||
|
Loading…
Reference in New Issue
Block a user