mirror of
https://github.com/atom/atom.git
synced 2026-02-16 01:25:13 -05:00
Indentation is used to determine foldable regions, if the last line matches TextMate's foldEndRegex it is included in the foldable region.
112 lines
3.9 KiB
CoffeeScript
112 lines
3.9 KiB
CoffeeScript
AceAdaptor = require 'ace-adaptor'
|
|
Range = require 'range'
|
|
TextMateBundle = require 'text-mate-bundle'
|
|
_ = require 'underscore'
|
|
|
|
module.exports =
|
|
class LanguageMode
|
|
pairedCharacters:
|
|
'(': ')'
|
|
'[': ']'
|
|
'{': '}'
|
|
'"': '"'
|
|
"'": "'"
|
|
|
|
constructor: (@editSession) ->
|
|
@buffer = @editSession.buffer
|
|
@aceMode = @requireAceMode()
|
|
|
|
@grammar = TextMateBundle.grammarForFileName(@editSession.buffer.getBaseName())
|
|
@aceAdaptor = new AceAdaptor(@editSession)
|
|
|
|
_.adviseBefore @editSession, 'insertText', (text) =>
|
|
return true if @editSession.hasMultipleCursors()
|
|
|
|
cursorBufferPosition = @editSession.getCursorBufferPosition()
|
|
nextCharachter = @editSession.getTextInBufferRange([cursorBufferPosition, cursorBufferPosition.add([0, 1])])
|
|
|
|
if @isCloseBracket(text) and text == nextCharachter
|
|
@editSession.moveCursorRight()
|
|
false
|
|
else if pairedCharacter = @pairedCharacters[text]
|
|
@editSession.insertText text + pairedCharacter
|
|
@editSession.moveCursorLeft()
|
|
false
|
|
|
|
requireAceMode: (fileExtension) ->
|
|
modeName = switch @editSession.buffer.getExtension()
|
|
when 'js' then 'javascript'
|
|
when 'coffee' then 'coffee'
|
|
when 'rb', 'ru' then 'ruby'
|
|
when 'c', 'h', 'cpp' then 'c_cpp'
|
|
when 'html', 'htm' then 'html'
|
|
when 'css' then 'css'
|
|
when 'java' then 'java'
|
|
when 'xml' then 'xml'
|
|
else 'text'
|
|
new (require("ace/mode/#{modeName}").Mode)
|
|
|
|
isOpenBracket: (string) ->
|
|
@pairedCharacters[string]?
|
|
|
|
isCloseBracket: (string) ->
|
|
@getInvertedPairedCharacters()[string]?
|
|
|
|
getInvertedPairedCharacters: ->
|
|
return @invertedPairedCharacters if @invertedPairedCharacters
|
|
|
|
@invertedPairedCharacters = {}
|
|
for open, close of @pairedCharacters
|
|
@invertedPairedCharacters[close] = open
|
|
@invertedPairedCharacters
|
|
|
|
toggleLineCommentsInRange: (range) ->
|
|
range = Range.fromObject(range)
|
|
@aceMode.toggleCommentLines(@tokenizedBuffer.stackForRow(range.start.row), @aceAdaptor, range.start.row, range.end.row)
|
|
|
|
doesBufferRowStartFold: (bufferRow) ->
|
|
return false if @editSession.isBufferRowBlank(bufferRow)
|
|
nextNonEmptyRow = @editSession.nextNonBlankBufferRow(bufferRow)
|
|
return false unless nextNonEmptyRow?
|
|
@editSession.indentationForBufferRow(nextNonEmptyRow) > @editSession.indentationForBufferRow(bufferRow)
|
|
|
|
rowRangeForFoldAtBufferRow: (bufferRow) ->
|
|
return null unless @doesBufferRowStartFold(bufferRow)
|
|
|
|
startIndentation = @editSession.indentationForBufferRow(bufferRow)
|
|
for row in [(bufferRow + 1)..@editSession.getLastBufferRow()]
|
|
continue if @editSession.isBufferRowBlank(row)
|
|
indentation = @editSession.indentationForBufferRow(row)
|
|
if indentation <= startIndentation
|
|
includeRowInFold = indentation == startIndentation and @grammar.foldEndRegex.search(@editSession.lineForBufferRow(row))
|
|
foldEndRow = row if includeRowInFold
|
|
break
|
|
|
|
foldEndRow = row
|
|
|
|
[bufferRow, foldEndRow]
|
|
|
|
indentationForRow: (row) ->
|
|
for precedingRow in [row - 1..-1]
|
|
return if precedingRow < 0
|
|
precedingLine = @editSession.buffer.lineForRow(precedingRow)
|
|
break if /\S/.test(precedingLine)
|
|
|
|
scopes = @tokenizedBuffer.scopesForPosition([precedingRow, Infinity])
|
|
indentation = precedingLine.match(/^\s*/)[0]
|
|
increaseIndentPattern = TextMateBundle.getPreferenceInScope(scopes[0], 'increaseIndentPattern')
|
|
decreaseIndentPattern = TextMateBundle.getPreferenceInScope(scopes[0], 'decreaseIndentPattern')
|
|
|
|
if new OnigRegExp(increaseIndentPattern).search(precedingLine)
|
|
indentation += @editSession.tabText
|
|
|
|
line = @editSession.buffer.lineForRow(row)
|
|
if new OnigRegExp(decreaseIndentPattern).search(line)
|
|
indentation = indentation.replace(@editSession.tabText, "")
|
|
|
|
indentation
|
|
|
|
getLineTokens: (line, stack) ->
|
|
{tokens, stack} = @grammar.getLineTokens(line, stack)
|
|
|