diff --git a/package.json b/package.json index 7e6619ab8..be07a083a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "0.201.0", + "version": "0.202.0", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { @@ -32,7 +32,7 @@ "delegato": "^1", "emissary": "^1.3.3", "event-kit": "^1.2.0", - "first-mate": "^4.1.4", + "first-mate": "^4.1.5", "fs-plus": "^2.8.0", "fstream": "0.1.24", "fuzzaldrin": "^2.1", @@ -109,13 +109,13 @@ "keybinding-resolver": "0.33.0", "link": "0.30.0", "markdown-preview": "0.149.0", - "metrics": "0.50.0", + "metrics": "0.51.0", "notifications": "0.50.0", "open-on-github": "0.37.0", "package-generator": "0.39.0", "release-notes": "0.52.0", - "settings-view": "0.204.0", - "snippets": "0.89.0", + "settings-view": "0.205.0", + "snippets": "0.90.0", "spell-check": "0.58.0", "status-bar": "0.72.0", "styleguide": "0.44.0", @@ -157,7 +157,7 @@ "language-text": "0.6.0", "language-todo": "0.21.0", "language-toml": "0.16.0", - "language-xml": "0.29.0", + "language-xml": "0.30.0", "language-yaml": "0.22.0" }, "private": true, diff --git a/resources/linux/debian/control.in b/resources/linux/debian/control.in index 1578f544b..cf2356a5d 100644 --- a/resources/linux/debian/control.in +++ b/resources/linux/debian/control.in @@ -1,6 +1,7 @@ Package: <%= name %> Version: <%= version %> Depends: git, gconf2, gconf-service, libgtk2.0-0, libudev0 | libudev1, libgcrypt11 | libgcrypt20, libnotify4, libxtst6, libnss3, python, gvfs-bin, xdg-utils +Recommends: lsb-release Suggests: libgnome-keyring0, gir1.2-gnomekeyring-1.0 Section: <%= section %> Priority: optional diff --git a/resources/linux/redhat/atom.spec.in b/resources/linux/redhat/atom.spec.in index 369aeea70..3bc37e83a 100644 --- a/resources/linux/redhat/atom.spec.in +++ b/resources/linux/redhat/atom.spec.in @@ -7,6 +7,8 @@ URL: https://atom.io/ AutoReqProv: no # Avoid libchromiumcontent.so missing dependency Prefix: <%= installDir %> +Requires: redhat-lsb-core + %description <%= description %> diff --git a/spec/display-buffer-spec.coffee b/spec/display-buffer-spec.coffee index 6389f8105..be89db8ac 100644 --- a/spec/display-buffer-spec.coffee +++ b/spec/display-buffer-spec.coffee @@ -106,8 +106,11 @@ describe "DisplayBuffer", -> buffer.setTextInRange([[0, 0], [1, 0]], 'abcdefghijklmnopqrstuvwxyz\n') displayBuffer.setEditorWidthInChars(10) expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe 'abcdefghij' + expect(displayBuffer.tokenizedLineForScreenRow(0).bufferDelta).toBe 'abcdefghij'.length expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe 'klmnopqrst' + expect(displayBuffer.tokenizedLineForScreenRow(1).bufferDelta).toBe 'klmnopqrst'.length expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe 'uvwxyz' + expect(displayBuffer.tokenizedLineForScreenRow(2).bufferDelta).toBe 'uvwxyz'.length describe "when there is a whitespace character at the max length boundary", -> it "wraps the line at the first non-whitespace character following the boundary", -> diff --git a/src/tokenized-line.coffee b/src/tokenized-line.coffee index 45af81e57..6761eecad 100644 --- a/src/tokenized-line.coffee +++ b/src/tokenized-line.coffee @@ -8,8 +8,26 @@ LeadingWhitespaceRegex = /^\s*/ TrailingWhitespaceRegex = /\s*$/ RepeatedSpaceRegex = /[ ]/g CommentScopeRegex = /(\b|\.)comment/ +TabCharCode = 9 +SpaceCharCode = 32 +SpaceString = ' ' +TabStringsByLength = { + 1: ' ' + 2: ' ' + 3: ' ' + 4: ' ' +} + idCounter = 1 +getTabString = (length) -> + TabStringsByLength[length] ?= buildTabString(length) + +buildTabString = (length) -> + string = SpaceString + string += SpaceString for i in [1...length] by 1 + string + module.exports = class TokenizedLine endOfLineInvisibles: null @@ -41,6 +59,9 @@ class TokenizedLine firstNonWhitespaceColumn = null lastNonWhitespaceColumn = null + substringStart = 0 + substringEnd = 0 + while bufferColumn < @text.length # advance to next token if we've iterated over its length if tokenOffset is @tags[tokenIndex] @@ -50,23 +71,23 @@ class TokenizedLine # advance to next token tag tokenIndex++ while @tags[tokenIndex] < 0 - character = @text[bufferColumn] + charCode = @text.charCodeAt(bufferColumn) # split out unicode surrogate pairs if isPairedCharacter(@text, bufferColumn) prefix = tokenOffset suffix = @tags[tokenIndex] - tokenOffset - 2 - splitTokens = [] - splitTokens.push(prefix) if prefix > 0 - splitTokens.push(2) - splitTokens.push(suffix) if suffix > 0 - @tags.splice(tokenIndex, 1, splitTokens...) + i = tokenIndex + @tags.splice(i, 1) + @tags.splice(i++, 0, prefix) if prefix > 0 + @tags.splice(i++, 0, 2) + @tags.splice(i, 0, suffix) if suffix > 0 firstNonWhitespaceColumn ?= screenColumn lastNonWhitespaceColumn = screenColumn + 1 - text += @text.substr(bufferColumn, 2) + substringEnd += 2 screenColumn += 2 bufferColumn += 2 @@ -76,38 +97,53 @@ class TokenizedLine tokenOffset = 0 # split out leading soft tabs - else if character is ' ' + else if charCode is SpaceCharCode if firstNonWhitespaceColumn? - text += ' ' + substringEnd += 1 else if (screenColumn + 1) % @tabLength is 0 @specialTokens[tokenIndex] = SoftTab suffix = @tags[tokenIndex] - @tabLength @tags.splice(tokenIndex, 1, @tabLength) @tags.splice(tokenIndex + 1, 0, suffix) if suffix > 0 - text += @invisibles?.space ? ' ' + + if @invisibles?.space + if substringEnd > substringStart + text += @text.substring(substringStart, substringEnd) + substringStart = substringEnd + text += @invisibles.space + substringStart += 1 + + substringEnd += 1 screenColumn++ bufferColumn++ tokenOffset++ # expand hard tabs to the next tab stop - else if character is '\t' + else if charCode is TabCharCode + if substringEnd > substringStart + text += @text.substring(substringStart, substringEnd) + substringStart = substringEnd + tabLength = @tabLength - (screenColumn % @tabLength) if @invisibles?.tab text += @invisibles.tab + text += getTabString(tabLength - 1) if tabLength > 1 else - text += ' ' - text += ' ' for i in [1...tabLength] by 1 + text += getTabString(tabLength) + + substringStart += 1 + substringEnd += 1 prefix = tokenOffset suffix = @tags[tokenIndex] - tokenOffset - 1 - splitTokens = [] - splitTokens.push(prefix) if prefix > 0 - splitTokens.push(tabLength) - splitTokens.push(suffix) if suffix > 0 - @tags.splice(tokenIndex, 1, splitTokens...) + i = tokenIndex + @tags.splice(i, 1) + @tags.splice(i++, 0, prefix) if prefix > 0 + @tags.splice(i++, 0, tabLength) + @tags.splice(i, 0, suffix) if suffix > 0 screenColumn += tabLength bufferColumn++ @@ -122,12 +158,17 @@ class TokenizedLine firstNonWhitespaceColumn ?= screenColumn lastNonWhitespaceColumn = screenColumn - text += character + substringEnd += 1 screenColumn++ bufferColumn++ tokenOffset++ - @text = text + if substringEnd > substringStart + unless substringStart is 0 and substringEnd is @text.length + text += @text.substring(substringStart, substringEnd) + @text = text + else + @text = text @firstNonWhitespaceIndex = firstNonWhitespaceColumn if lastNonWhitespaceColumn? @@ -381,7 +422,7 @@ class TokenizedLine rightFragment.tags = rightTags rightFragment.specialTokens = rightSpecialTokens rightFragment.startBufferColumn = splitBufferColumn - rightFragment.bufferDelta = @bufferDelta - splitBufferColumn + rightFragment.bufferDelta = @startBufferColumn + @bufferDelta - splitBufferColumn rightFragment.ruleStack = @ruleStack rightFragment.invisibles = @invisibles rightFragment.lineEnding = @lineEnding