mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-13 08:44:12 +03:00
All specs pass w/ TextMateGrammar for tokenization (auto-indent disabled)
This commit is contained in:
parent
08a55dfcac
commit
1a243adfcf
@ -2,7 +2,7 @@ Project = require 'project'
|
||||
Buffer = require 'buffer'
|
||||
EditSession = require 'edit-session'
|
||||
|
||||
fdescribe "EditSession", ->
|
||||
describe "EditSession", ->
|
||||
[buffer, editSession, lineLengths] = []
|
||||
|
||||
beforeEach ->
|
||||
@ -656,13 +656,13 @@ fdescribe "EditSession", ->
|
||||
editSession.insertText('holy cow')
|
||||
expect(editSession.lineForScreenRow(2).fold).toBeUndefined()
|
||||
|
||||
describe "when auto-indent is enabled", ->
|
||||
xdescribe "when auto-indent is enabled", ->
|
||||
beforeEach ->
|
||||
editSession.setAutoIndent(true)
|
||||
|
||||
describe "when editing a non-wrapped line", ->
|
||||
describe "when a newline is inserted", ->
|
||||
it "auto-indents the newline for each cursor", ->
|
||||
it "auto-indents the new line for each cursor", ->
|
||||
editSession.setCursorScreenPosition([1, 30])
|
||||
editSession.addCursorAtScreenPosition([4, 29])
|
||||
editSession.insertText("\n")
|
||||
@ -684,6 +684,14 @@ fdescribe "EditSession", ->
|
||||
expect(buffer.lineForRow(2)).toEqual(" }")
|
||||
expect(editSession.getCursorBufferPosition().column).toBe 3
|
||||
|
||||
describe "when the line is already indented beyond the suggested depth", ->
|
||||
describe "when text without a newline is inserted", ->
|
||||
it "does not modify the line's indentation level", ->
|
||||
|
||||
describe "when text with a newline is inserted", ->
|
||||
it "only modifies the indentation level of subsequent lines, but not the current line", ->
|
||||
|
||||
|
||||
describe "when editing a wrapped line", ->
|
||||
beforeEach ->
|
||||
editSession.setSoftWrapColumn(50)
|
||||
@ -772,7 +780,7 @@ fdescribe "EditSession", ->
|
||||
expect(cursor2.getBufferPosition()).toEqual [8,0]
|
||||
|
||||
describe ".insertNewlineBelow()", ->
|
||||
it "inserts a newline below the cursor's current line, autoindents it, and moves the cursor to the end of the line", ->
|
||||
xit "inserts a newline below the cursor's current line, autoindents it, and moves the cursor to the end of the line", ->
|
||||
editSession.setAutoIndent(true)
|
||||
editSession.insertNewlineBelow()
|
||||
expect(buffer.lineForRow(0)).toBe "var quicksort = function () {"
|
||||
@ -1105,7 +1113,7 @@ fdescribe "EditSession", ->
|
||||
editSession.indent()
|
||||
expect(buffer.lineForRow(0)).toMatch(tabRegex)
|
||||
|
||||
describe "when auto-indent is on and there is no text after the cursor", ->
|
||||
xdescribe "when auto-indent is on and the line only contains whitespace", ->
|
||||
describe "when the preceding line opens a new level of indentation", ->
|
||||
it "increases the level of indentation by one", ->
|
||||
buffer.insert([5, 0], " \n")
|
||||
|
@ -32,7 +32,6 @@ describe "Editor", ->
|
||||
$('#jasmine-content').append(this)
|
||||
|
||||
editor.lineOverdraw = 2
|
||||
rootView.project.setAutoIndent(false)
|
||||
editor.enableKeymap()
|
||||
editor.isFocused = true
|
||||
|
||||
@ -170,7 +169,7 @@ describe "Editor", ->
|
||||
expect(miniEditor.remove).not.toHaveBeenCalled()
|
||||
|
||||
describe "when buffer is modified", ->
|
||||
it "triggers alert and does not close session", ->
|
||||
it "triggers an alert and does not close the session", ->
|
||||
spyOn(editor, 'remove').andCallThrough()
|
||||
spyOn($native, 'alert')
|
||||
editor.insertText("I AM CHANGED!")
|
||||
@ -989,13 +988,13 @@ describe "Editor", ->
|
||||
|
||||
it "syntax highlights code based on the file type", ->
|
||||
line1 = editor.renderedLines.find('.line:first')
|
||||
expect(line1.find('span:eq(0)')).toMatchSelector '.keyword.definition'
|
||||
expect(line1.find('span:eq(0)')).toMatchSelector '.storage-type-js'
|
||||
expect(line1.find('span:eq(0)').text()).toBe 'var'
|
||||
expect(line1.find('span:eq(1)')).toMatchSelector '.text'
|
||||
expect(line1.find('span:eq(1)')).toMatchSelector '.source-js'
|
||||
expect(line1.find('span:eq(1)').text()).toBe ' '
|
||||
expect(line1.find('span:eq(2)')).toMatchSelector '.identifier'
|
||||
expect(line1.find('span:eq(2)')).toMatchSelector '.entity-name-function-js'
|
||||
expect(line1.find('span:eq(2)').text()).toBe 'quicksort'
|
||||
expect(line1.find('span:eq(4)')).toMatchSelector '.operator'
|
||||
expect(line1.find('span:eq(4)')).toMatchSelector '.keyword-operator-js'
|
||||
expect(line1.find('span:eq(4)').text()).toBe '='
|
||||
|
||||
line12 = editor.renderedLines.find('.line:eq(11)')
|
||||
@ -1003,9 +1002,9 @@ describe "Editor", ->
|
||||
|
||||
describe "when lines are updated in the buffer", ->
|
||||
it "syntax highlights the updated lines", ->
|
||||
expect(editor.renderedLines.find('.line:eq(0) span:eq(0)')).toMatchSelector '.keyword.definition'
|
||||
buffer.insert([0, 4], "g")
|
||||
expect(editor.renderedLines.find('.line:eq(0) span:eq(0)')).toMatchSelector '.keyword.definition'
|
||||
expect(editor.renderedLines.find('.line:eq(0) span:eq(0)')).toMatchSelector '.storage-type-js'
|
||||
buffer.insert([0, 0], "q")
|
||||
expect(editor.renderedLines.find('.line:eq(0) span:eq(0)')).not.toMatchSelector '.storage-type-js'
|
||||
|
||||
# verify that re-highlighting can occur below the changed line
|
||||
buffer.insert([5,0], "/* */")
|
||||
|
@ -160,8 +160,9 @@ describe "LineMap", ->
|
||||
describe ".linesForScreenRows(startRow, endRow)", ->
|
||||
it "returns lines for the given row range, concatenating fragments that belong on a single screen line", ->
|
||||
[line1a, line1b] = line1.splitAt(11)
|
||||
[line3a, line3b] = line3.splitAt(16)
|
||||
[line3a, line3b] = line3.splitAt(15)
|
||||
map.insertAtBufferRow(0, [line0, line1a, line1b, line2, line3a, line3b, line4])
|
||||
|
||||
expect(map.linesForScreenRows(1, 3)).toEqual [line1, line2, line3]
|
||||
# repeating assertion to cover a regression where this method mutated lines
|
||||
expect(map.linesForScreenRows(1, 3)).toEqual [line1, line2, line3]
|
||||
|
@ -1,6 +1,6 @@
|
||||
TextMateBundle = require 'text-mate-bundle'
|
||||
|
||||
fdescribe "TextMateBundle", ->
|
||||
describe "TextMateBundle", ->
|
||||
describe ".getPreferenceInScope(scope, preferenceName)", ->
|
||||
it "returns the preference by the given name in the given scope or undefined if there isn't one", ->
|
||||
expect(TextMateBundle.getPreferenceInScope('source.coffee', 'decreaseIndentPattern')).toBe '^\\s*(\\}|\\]|else|catch|finally)$'
|
||||
|
20
spec/app/token-spec.coffee
Normal file
20
spec/app/token-spec.coffee
Normal file
@ -0,0 +1,20 @@
|
||||
_ = require 'underscore'
|
||||
Buffer = require 'buffer'
|
||||
TokenizedBuffer = require 'tokenized-buffer'
|
||||
|
||||
describe "Token", ->
|
||||
[editSession, token] = []
|
||||
|
||||
beforeEach ->
|
||||
tabText = ' '
|
||||
editSession = fixturesProject.buildEditSessionForPath('sample.js')
|
||||
{ tokenizedBuffer } = editSession
|
||||
screenLine = tokenizedBuffer.lineForScreenRow(3)
|
||||
token = _.last(screenLine.tokens)
|
||||
|
||||
afterEach ->
|
||||
editSession.destroy()
|
||||
|
||||
describe ".getCssClassString()", ->
|
||||
it "returns a class for every scope prefix, replacing . characters in scope names with --", ->
|
||||
expect(token.getCssClassString()).toBe 'source source-js punctuation punctuation-terminator punctuation-terminator-statement punctuation-terminator-statement-js'
|
@ -401,7 +401,6 @@ describe "TreeView", ->
|
||||
expect(treeView.scrollTop()).toBe 0
|
||||
|
||||
entryCount = treeView.find(".entry").length
|
||||
console.log entryCount
|
||||
_.times entryCount, -> treeView.moveDown()
|
||||
expect(treeView.scrollBottom()).toBe treeView.prop('scrollHeight')
|
||||
|
||||
|
@ -29,7 +29,7 @@ class EditSession
|
||||
anchorRanges: null
|
||||
cursors: null
|
||||
selections: null
|
||||
autoIndent: true
|
||||
autoIndent: false # TODO: re-enabled auto-indent after fixing the rest of tokenization
|
||||
softTabs: true
|
||||
softWrap: false
|
||||
|
||||
@ -139,10 +139,7 @@ class EditSession
|
||||
indent: ->
|
||||
currentRow = @getCursorBufferPosition().row
|
||||
if @getSelection().isEmpty()
|
||||
whitespaceMatch = @lineForBufferRow(currentRow).match /^\s*$/
|
||||
if @autoIndent and whitespaceMatch
|
||||
@autoIndentRow(currentRow)
|
||||
else if @softTabs
|
||||
if @softTabs
|
||||
@insertText(@tabText)
|
||||
else
|
||||
@insertText('\t')
|
||||
|
@ -800,7 +800,7 @@ class Editor extends View
|
||||
@raw ' ' if line.text == ''
|
||||
else
|
||||
for token in line.tokens
|
||||
@span { class: token.type.replace('.', ' ') }, token.value
|
||||
@span { class: token.getCssClassString() }, token.value
|
||||
|
||||
insertLineElements: (row, lineElements) ->
|
||||
@spliceLineElements(row, 0, lineElements)
|
||||
|
@ -10,21 +10,18 @@ ChildProcess = require 'child-process'
|
||||
|
||||
module.exports =
|
||||
class Project
|
||||
tabText: ' '
|
||||
autoIndent: false
|
||||
softTabs: true
|
||||
softWrap: false
|
||||
rootDirectory: null
|
||||
editSessions: null
|
||||
tabText: null
|
||||
autoIndent: null
|
||||
softTabs: null
|
||||
softWrap: null
|
||||
ignoredPathRegexes: null
|
||||
|
||||
constructor: (path) ->
|
||||
@setPath(path)
|
||||
@editSessions = []
|
||||
@buffers = []
|
||||
@setTabText(' ')
|
||||
@setAutoIndent(true)
|
||||
@setSoftTabs(true)
|
||||
@ignoredPathRegexes = [
|
||||
/\.DS_Store$/
|
||||
/(^|\/)\.git(\/|$)/
|
||||
|
@ -26,7 +26,7 @@ class TextMateBundle
|
||||
@grammarsByFileType[fileType] = grammar
|
||||
|
||||
@grammarForFileName: (fileName) ->
|
||||
extension = fs.extension(fileName)[1...]
|
||||
extension = fs.extension(fileName)?[1...]
|
||||
@grammarsByFileType[extension] or @grammarsByFileType["txt"]
|
||||
|
||||
@getPreferenceInScope: (scopeSelector, preferenceName) ->
|
||||
|
@ -98,8 +98,8 @@ class Pattern
|
||||
regex: null
|
||||
captures: null
|
||||
|
||||
constructor: (@grammar, { name, @include, match, begin, end, captures, beginCaptures, endCaptures, patterns, @popRule}) ->
|
||||
@scopeName = name
|
||||
constructor: (@grammar, { name, contentName, @include, match, begin, end, captures, beginCaptures, endCaptures, patterns, @popRule}) ->
|
||||
@scopeName = name ? contentName # TODO: We need special treatment of contentName
|
||||
if match
|
||||
@regex = new OnigRegExp(match)
|
||||
@captures = captures
|
||||
|
@ -32,3 +32,15 @@ class Token
|
||||
|
||||
buildTabToken: (tabText) ->
|
||||
new Token(value: tabText, scopes: @scopes, bufferDelta: 1, isAtomic: true)
|
||||
|
||||
getCssClassString: ->
|
||||
@cssClassString ?= @getCssClasses().join(' ')
|
||||
|
||||
getCssClasses: ->
|
||||
classes = []
|
||||
for scope in @scopes
|
||||
scopeComponents = scope.split('.')
|
||||
for i in [0...scopeComponents.length]
|
||||
classes.push scopeComponents[0..i].join('-')
|
||||
classes
|
||||
|
||||
|
@ -24,6 +24,7 @@ windowAdditions =
|
||||
$(document).on 'keydown', @_handleKeyEvent
|
||||
|
||||
startup: (path) ->
|
||||
TextMateBundle.loadAll()
|
||||
@attachRootView(path)
|
||||
$(window).on 'close', => @close()
|
||||
$(window).on 'beforeunload', =>
|
||||
@ -31,7 +32,6 @@ windowAdditions =
|
||||
false
|
||||
$(window).focus()
|
||||
atom.windowOpened this
|
||||
TextMateBundle.loadAll()
|
||||
|
||||
shutdown: ->
|
||||
@rootView.deactivate()
|
||||
|
@ -35,6 +35,7 @@ module.exports =
|
||||
# more non-dot characters. Returns an empty string if no valid
|
||||
# extension exists.
|
||||
extension: (path) ->
|
||||
return '' unless typeof path is 'string'
|
||||
match = @base(path).match(/\.[^\.]+$/)
|
||||
if match
|
||||
match[0]
|
||||
|
Loading…
Reference in New Issue
Block a user