diff --git a/spec/app/buffer-spec.coffee b/spec/app/buffer-spec.coffee
index a93bae30a..ea10907cf 100644
--- a/spec/app/buffer-spec.coffee
+++ b/spec/app/buffer-spec.coffee
@@ -833,3 +833,51 @@ describe 'Buffer', ->
expect(buffer.getText()).toBe "a"
buffer.append("b\nc");
expect(buffer.getText()).toBe "ab\nc"
+
+ describe "line ending support", ->
+ describe ".lineEndingForRow(line)", ->
+ it "return the line ending for each buffer line", ->
+ buffer.setText("a\r\nb\nc")
+ expect(buffer.lineEndingForRow(0)).toBe '\r\n'
+ expect(buffer.lineEndingForRow(1)).toBe '\n'
+ expect(buffer.lineEndingForRow(2)).toBeUndefined()
+
+ describe ".lineForRow(line)", ->
+ it "returns the line text without the line ending for both lf and crlf lines", ->
+ buffer.setText("a\r\nb\nc")
+ expect(buffer.lineForRow(0)).toBe 'a'
+ expect(buffer.lineForRow(1)).toBe 'b'
+ expect(buffer.lineForRow(2)).toBe 'c'
+
+ describe ".getText()", ->
+ it "returns the text with the corrent line endings for each row", ->
+ buffer.setText("a\r\nb\nc")
+ expect(buffer.getText()).toBe "a\r\nb\nc"
+ buffer.setText("a\r\nb\nc\n")
+ expect(buffer.getText()).toBe "a\r\nb\nc\n"
+
+ describe "when editing a line", ->
+ it "preserves the existing line ending", ->
+ buffer.setText("a\r\nb\nc")
+ buffer.insert([0, 1], "1")
+ expect(buffer.getText()).toBe "a1\r\nb\nc"
+
+ describe "when inserting text with multiple lines", ->
+ describe "when the current line has a line ending", ->
+ it "uses the same line ending as the line where the text is inserted", ->
+ buffer.setText("a\r\n")
+ buffer.insert([0,1], "hello\n1\n\n2")
+ expect(buffer.getText()).toBe "ahello\r\n1\r\n\r\n2\r\n"
+
+ describe "when the current line has no line ending (because it's the last line of the buffer)", ->
+ describe "when the buffer contains only a single line", ->
+ it "honors the line endings in the inserted text", ->
+ buffer.setText("initialtext")
+ buffer.append("hello\n1\r\n2\n")
+ expect(buffer.getText()).toBe "initialtexthello\n1\r\n2\n"
+
+ describe "when the buffer contains a preceding line", ->
+ it "uses the line ending of the preceding line", ->
+ buffer.setText("\ninitialtext")
+ buffer.append("hello\n1\r\n2\n")
+ expect(buffer.getText()).toBe "\ninitialtexthello\n1\n2\n"
diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee
index dd67f2946..445f2faf1 100644
--- a/spec/app/editor-spec.coffee
+++ b/spec/app/editor-spec.coffee
@@ -1604,6 +1604,20 @@ describe "Editor", ->
expect(rightEditor.find(".line:first").text()).toBe "_tab _;"
expect(leftEditor.find(".line:first").text()).toBe "_tab _;"
+ it "displays trailing carriage return using a visible non-empty value", ->
+ editor.setText "a line that ends with a carriage return\r\n"
+ editor.attachToDom()
+
+ expect(config.get("editor.showInvisibles")).toBeFalsy()
+ expect(editor.renderedLines.find('.line:first').text()).toBe "a line that ends with a carriage return"
+
+ config.set("editor.showInvisibles", true)
+ cr = editor.invisibles?.cr
+ expect(cr).toBeTruthy()
+ eol = editor.invisibles?.eol
+ expect(eol).toBeTruthy()
+ expect(editor.renderedLines.find('.line:first').text()).toBe "a line that ends with a carriage return#{cr}#{eol}"
+
describe "gutter rendering", ->
beforeEach ->
editor.attachToDom(heightInLines: 5.5)
@@ -2212,3 +2226,8 @@ describe "Editor", ->
edited = editor.replaceSelectedText(replacer)
expect(replaced).toBe true
expect(edited).toBe false
+
+ describe "when editor:copy-path is triggered", ->
+ it "copies the absolute path to the editor's file to the pasteboard", ->
+ editor.trigger 'editor:copy-path'
+ expect(pasteboard.read()[0]).toBe editor.getPath()
diff --git a/spec/app/language-mode-spec.coffee b/spec/app/language-mode-spec.coffee
index 9e1cd8b71..775baefa1 100644
--- a/spec/app/language-mode-spec.coffee
+++ b/spec/app/language-mode-spec.coffee
@@ -308,16 +308,16 @@ describe "LanguageMode", ->
expect(buffer.lineForRow(3)).toBe " font-weight: bold !important;"
it "uncomments lines with leading whitespace", ->
- buffer.replaceLines(2, 2, " /*width: 110%;*/")
+ buffer.change([[2, 0], [2, Infinity]], " /*width: 110%;*/")
languageMode.toggleLineCommentsForBufferRows(2, 2)
expect(buffer.lineForRow(2)).toBe " width: 110%;"
it "uncomments lines with trailing whitespace", ->
- buffer.replaceLines(2, 2, "/*width: 110%;*/ ")
+ buffer.change([[2, 0], [2, Infinity]], "/*width: 110%;*/ ")
languageMode.toggleLineCommentsForBufferRows(2, 2)
expect(buffer.lineForRow(2)).toBe "width: 110%; "
it "uncomments lines with leading and trailing whitespace", ->
- buffer.replaceLines(2, 2, " /*width: 110%;*/ ")
+ buffer.change([[2, 0], [2, Infinity]], " /*width: 110%;*/ ")
languageMode.toggleLineCommentsForBufferRows(2, 2)
expect(buffer.lineForRow(2)).toBe " width: 110%; "
diff --git a/spec/app/select-list-spec.coffee b/spec/app/select-list-spec.coffee
index 01ffeb445..a39c4a128 100644
--- a/spec/app/select-list-spec.coffee
+++ b/spec/app/select-list-spec.coffee
@@ -59,6 +59,17 @@ describe "SelectList", ->
expect(selectList.error).not.toBeVisible()
expect(selectList).not.toHaveClass("error")
+ it "displays no elements until the array has been set on the list", ->
+ selectList.array = null
+ selectList.list.empty()
+ miniEditor.insertText('la')
+ window.advanceClock(selectList.inputThrottle)
+
+ expect(list.find('li').length).toBe 0
+ expect(selectList).not.toHaveClass("error")
+ selectList.setArray(array)
+ expect(list.find('li').length).toBe 2
+
describe "when core:move-up / core:move-down are triggered on the miniEditor", ->
it "selects the previous / next item in the list, or wraps around to the other side", ->
expect(list.find('li:first')).toHaveClass 'selected'
@@ -153,3 +164,16 @@ describe "SelectList", ->
miniEditor.trigger 'focusout'
expect(selectList.cancelled).toHaveBeenCalled()
expect(selectList.detach).toHaveBeenCalled()
+
+ describe "the core:move-to-top event", ->
+ it "scrolls to the top and selects the first element", ->
+ selectList.trigger 'core:move-down'
+ expect(list.find('li:eq(1)')).toHaveClass 'selected'
+ selectList.trigger 'core:move-to-top'
+ expect(list.find('li:first')).toHaveClass 'selected'
+
+ describe "the core:move-to-bottom event", ->
+ it "scrolls to the bottom and selects the last element", ->
+ expect(list.find('li:first')).toHaveClass 'selected'
+ selectList.trigger 'core:move-to-bottom'
+ expect(list.find('li:last')).toHaveClass 'selected'
diff --git a/src/app/atom-package.coffee b/src/app/atom-package.coffee
index 8fc6b4908..bb1ce071b 100644
--- a/src/app/atom-package.coffee
+++ b/src/app/atom-package.coffee
@@ -16,7 +16,7 @@ class AtomPackage extends Package
@loadMetadata()
@loadKeymaps()
@loadStylesheets() if @autoloadStylesheets
- rootView.activatePackage(@name, this) unless @isDirectory
+ rootView?.activatePackage(@name, this) unless @isDirectory
catch e
console.warn "Failed to load package named '#{@name}'", e.stack
this
diff --git a/src/app/buffer-change-operation.coffee b/src/app/buffer-change-operation.coffee
index 6fd0f2654..2a31ab244 100644
--- a/src/app/buffer-change-operation.coffee
+++ b/src/app/buffer-change-operation.coffee
@@ -1,4 +1,5 @@
Range = require 'range'
+_ = require 'underscore'
module.exports =
class BufferChangeOperation
@@ -8,7 +9,8 @@ class BufferChangeOperation
newRange: null
newText: null
- constructor: ({@buffer, @oldRange, @newText}) ->
+ constructor: ({@buffer, @oldRange, @newText, @options}) ->
+ @options ?= {}
do: ->
@oldText = @buffer.getTextInRange(@oldRange)
@@ -26,18 +28,39 @@ class BufferChangeOperation
oldText: @newText
newText: @oldText
+ splitLines: (text) ->
+ lines = text.split('\n')
+ lineEndings = []
+ for line, index in lines
+ if _.endsWith(line, '\r')
+ lines[index] = line[0..-2]
+ lineEndings[index] = '\r\n'
+ else
+ lineEndings[index] = '\n'
+ {lines, lineEndings}
+
changeBuffer: ({ oldRange, newRange, newText, oldText }) ->
{ prefix, suffix } = @buffer.prefixAndSuffixForRange(oldRange)
- newTextLines = newText.split('\n')
- if newTextLines.length == 1
- newTextLines = [prefix + newText + suffix]
- else
- lastLineIndex = newTextLines.length - 1
- newTextLines[0] = prefix + newTextLines[0]
- newTextLines[lastLineIndex] += suffix
+ {lines, lineEndings} = @splitLines(newText)
+ lastLineIndex = lines.length - 1
- @buffer.replaceLines(oldRange.start.row, oldRange.end.row, newTextLines)
+ if lines.length == 1
+ lines = [prefix + newText + suffix]
+ else
+ lines[0] = prefix + lines[0]
+ lines[lastLineIndex] += suffix
+
+ startRow = oldRange.start.row
+ endRow = oldRange.end.row
+
+ normalizeLineEndings = @options.normalizeLineEndings ? true
+ if normalizeLineEndings and suggestedLineEnding = @buffer.suggestedLineEndingForRow(startRow)
+ lineEndings[index] = suggestedLineEnding for index in [0..lastLineIndex]
+ @buffer.lines[startRow..endRow] = lines
+ @buffer.lineEndings[startRow..endRow] = lineEndings
+ @buffer.cachedMemoryContents = null
+ @buffer.conflict = false if @buffer.conflict and !@buffer.isModified()
event = { oldRange, newRange, oldText, newText }
@buffer.trigger 'changed', event
@@ -47,11 +70,11 @@ class BufferChangeOperation
calculateNewRange: (oldRange, newText) ->
newRange = new Range(oldRange.start.copy(), oldRange.start.copy())
- newTextLines = newText.split('\n')
- if newTextLines.length == 1
+ {lines} = @splitLines(newText)
+ if lines.length == 1
newRange.end.column += newText.length
else
- lastLineIndex = newTextLines.length - 1
+ lastLineIndex = lines.length - 1
newRange.end.row += lastLineIndex
- newRange.end.column = newTextLines[lastLineIndex].length
+ newRange.end.column = lines[lastLineIndex].length
newRange
diff --git a/src/app/buffer.coffee b/src/app/buffer.coffee
index 9b205b7e0..266b30ba2 100644
--- a/src/app/buffer.coffee
+++ b/src/app/buffer.coffee
@@ -19,6 +19,7 @@ class Buffer
cachedMemoryContents: null
conflict: false
lines: null
+ lineEndings: null
file: null
anchors: null
anchorRanges: null
@@ -29,6 +30,7 @@ class Buffer
@anchors = []
@anchorRanges = []
@lines = ['']
+ @lineEndings = []
if path
throw "Path '#{path}' does not exist" unless fs.exists(path)
@@ -104,10 +106,10 @@ class Buffer
null
getText: ->
- @cachedMemoryContents ?= @lines.join('\n')
+ @cachedMemoryContents ?= @getTextInRange(@getRange())
setText: (text) ->
- @change(@getRange(), text)
+ @change(@getRange(), text, normalizeLineEndings: false)
getRange: ->
new Range([0, 0], [@getLastRow(), @getLastLine().length])
@@ -118,12 +120,14 @@ class Buffer
return @lines[range.start.row][range.start.column...range.end.column]
multipleLines = []
- multipleLines.push @lines[range.start.row][range.start.column..] # first line
+ multipleLines.push @lineForRow(range.start.row)[range.start.column..] # first line
+ multipleLines.push @lineEndingForRow(range.start.row)
for row in [range.start.row + 1...range.end.row]
- multipleLines.push @lines[row] # middle lines
- multipleLines.push @lines[range.end.row][0...range.end.column] # last line
+ multipleLines.push @lineForRow(row) # middle lines
+ multipleLines.push @lineEndingForRow(row)
+ multipleLines.push @lineForRow(range.end.row)[0...range.end.column] # last line
- return multipleLines.join '\n'
+ return multipleLines.join ''
getLines: ->
@lines
@@ -131,6 +135,12 @@ class Buffer
lineForRow: (row) ->
@lines[row]
+ lineEndingForRow: (row) ->
+ @lineEndings[row] unless row is @getLastRow()
+
+ suggestedLineEndingForRow: (row) ->
+ @lineEndingForRow(row) ? @lineEndingForRow(row - 1)
+
lineLengthForRow: (row) ->
@lines[row].length
@@ -195,9 +205,9 @@ class Buffer
delete: (range) ->
@change(range, '')
- change: (oldRange, newText) ->
+ change: (oldRange, newText, options) ->
oldRange = Range.fromObject(oldRange)
- operation = new BufferChangeOperation({buffer: this, oldRange, newText})
+ operation = new BufferChangeOperation({buffer: this, oldRange, newText, options})
range = @pushOperation(operation)
range
@@ -214,11 +224,6 @@ class Buffer
prefix: @lines[range.start.row][0...range.start.column]
suffix: @lines[range.end.row][range.end.column..]
- replaceLines: (startRow, endRow, newLines) ->
- @lines[startRow..endRow] = newLines
- @cachedMemoryContents = null
- @conflict = false if @conflict and !@isModified()
-
pushOperation: (operation, editSession) ->
if @undoManager
@undoManager.pushOperation(operation, editSession)
diff --git a/src/app/deferred-atom-package.coffee b/src/app/deferred-atom-package.coffee
index 5b040e3a9..1f328fc02 100644
--- a/src/app/deferred-atom-package.coffee
+++ b/src/app/deferred-atom-package.coffee
@@ -1,4 +1,5 @@
AtomPackage = require 'atom-package'
+_ = require 'underscore'
module.exports =
class DeferredAtomPackage extends AtomPackage
@@ -10,8 +11,13 @@ class DeferredAtomPackage extends AtomPackage
activate: (@rootView, @state) ->
@instance = null
- for event in @loadEvents
- @rootView.command event, (e) => @onLoadEvent(e, @getInstance())
+ onLoadEvent = (e) => @onLoadEvent(e, @getInstance())
+ if _.isArray(@loadEvents)
+ for event in @loadEvents
+ @rootView.command(event, onLoadEvent)
+ else
+ for event, selector of @loadEvents
+ @rootView.command(event, selector, onLoadEvent)
this
deactivate: -> @instance?.deactivate?()
diff --git a/src/app/editor.coffee b/src/app/editor.coffee
index a40f02a18..ce86c005f 100644
--- a/src/app/editor.coffee
+++ b/src/app/editor.coffee
@@ -182,6 +182,7 @@ class Editor extends View
'editor:close-other-edit-sessions': @destroyInactiveEditSessions
'editor:close-all-edit-sessions': @destroyAllEditSessions
'editor:select-grammar': @selectGrammar
+ 'editor:copy-path': @copyPathToPasteboard
documentation = {}
for name, method of editorBindings
@@ -310,9 +311,10 @@ class Editor extends View
setInvisibles: (@invisibles={}) ->
_.defaults @invisibles,
- eol: '\u00ac',
- space: '\u2022',
+ eol: '\u00ac'
+ space: '\u2022'
tab: '\u00bb'
+ cr: '\u00a4'
@resetDisplay()
checkoutHead: -> @getBuffer().checkoutHead()
@@ -1079,8 +1081,11 @@ class Editor extends View
position += token.value.length
popScope() while scopeStack.length > 0
- if not @mini and invisibles?.eol
- line.push("#{invisibles.eol}")
+ if invisibles and not @mini
+ if invisibles.cr and screenLine.lineEnding is '\r\n'
+ line.push("#{invisibles.cr}")
+ if invisibles.eol
+ line.push("#{invisibles.eol}")
line.push('')
line.join('')
@@ -1159,3 +1164,7 @@ class Editor extends View
@insertText(text, select: true)
true
+
+ copyPathToPasteboard: ->
+ path = @getPath()
+ pasteboard.write(path) if path?
diff --git a/src/app/keymaps/atom.cson b/src/app/keymaps/atom.cson
index a4f64a990..97c080d26 100644
--- a/src/app/keymaps/atom.cson
+++ b/src/app/keymaps/atom.cson
@@ -27,6 +27,7 @@
'meta-+': 'window:increase-font-size'
'meta--': 'window:decrease-font-size'
'ctrl-w w': 'window:focus-next-pane'
+ 'ctrl-tab': 'window:focus-next-pane'
'alt-meta-i': 'toggle-dev-tools'
diff --git a/src/app/keymaps/editor.cson b/src/app/keymaps/editor.cson
index 2f48d27bb..06f0dd571 100644
--- a/src/app/keymaps/editor.cson
+++ b/src/app/keymaps/editor.cson
@@ -36,4 +36,5 @@
'meta-U': 'editor:lower-case'
'alt-meta-w': 'editor:close-other-edit-sessions'
'meta-P': 'editor:close-all-edit-sessions'
- 'meta-l': 'editor:select-grammar'
+ 'meta-L': 'editor:select-grammar'
+ 'ctrl-C': 'editor:copy-path'
diff --git a/src/app/root-view.coffee b/src/app/root-view.coffee
index 3a187d6a7..4063ee863 100644
--- a/src/app/root-view.coffee
+++ b/src/app/root-view.coffee
@@ -18,7 +18,7 @@ class RootView extends View
disabledPackages: []
@content: ->
- @div id: 'root-view', tabindex: -1, =>
+ @div id: 'root-view', tabindex: 0, =>
@div id: 'horizontal', outlet: 'horizontal', =>
@div id: 'vertical', outlet: 'vertical', =>
@div id: 'panes', outlet: 'panes'
diff --git a/src/app/screen-line.coffee b/src/app/screen-line.coffee
index 31d93e879..2d01a07b1 100644
--- a/src/app/screen-line.coffee
+++ b/src/app/screen-line.coffee
@@ -2,7 +2,7 @@ _ = require 'underscore'
module.exports =
class ScreenLine
- constructor: ({tokens, @ruleStack, @bufferRows, @startBufferColumn, @fold, tabLength}) ->
+ constructor: ({tokens, @lineEnding, @ruleStack, @bufferRows, @startBufferColumn, @fold, tabLength}) ->
@tokens = @breakOutAtomicTokens(tokens, tabLength)
@bufferRows ?= 1
@startBufferColumn ?= 0
diff --git a/src/app/select-list.coffee b/src/app/select-list.coffee
index 020aaf734..0b4cd9a87 100644
--- a/src/app/select-list.coffee
+++ b/src/app/select-list.coffee
@@ -26,6 +26,12 @@ class SelectList extends View
@miniEditor.on 'focusout', => @cancel() unless @cancelling
@on 'core:move-up', => @selectPreviousItem()
@on 'core:move-down', => @selectNextItem()
+ @on 'core:move-to-top', =>
+ @selectItem(@list.find('li:first'))
+ @list.scrollToTop()
+ @on 'core:move-to-bottom', =>
+ @selectItem(@list.find('li:last'))
+ @list.scrollToBottom()
@on 'core:confirm', => @confirmSelection()
@on 'core:cancel', => @cancel()
@@ -62,6 +68,8 @@ class SelectList extends View
@loading.text(message).show()
populateList: ->
+ return unless @array?
+
filterQuery = @miniEditor.getText()
if filterQuery.length
filteredArray = fuzzyFilter(@array, filterQuery, key: @filterKey)
diff --git a/src/app/tokenized-buffer.coffee b/src/app/tokenized-buffer.coffee
index 6646fd54f..9e0930bf0 100644
--- a/src/app/tokenized-buffer.coffee
+++ b/src/app/tokenized-buffer.coffee
@@ -137,8 +137,9 @@ class TokenizedBuffer
buildTokenizedScreenLineForRow: (row, ruleStack) ->
line = @buffer.lineForRow(row)
+ lineEnding = @buffer.lineEndingForRow(row)
{ tokens, ruleStack } = @languageMode.tokenizeLine(line, ruleStack, row is 0)
- new ScreenLine({tokens, ruleStack, @tabLength})
+ new ScreenLine({tokens, ruleStack, @tabLength, lineEnding})
lineForScreenRow: (row) ->
@linesForScreenRows(row, row)[0]
diff --git a/src/packages/command-panel/spec/command-panel-spec.coffee b/src/packages/command-panel/spec/command-panel-spec.coffee
index f4dc193ef..635613912 100644
--- a/src/packages/command-panel/spec/command-panel-spec.coffee
+++ b/src/packages/command-panel/spec/command-panel-spec.coffee
@@ -180,17 +180,19 @@ describe "CommandPanel", ->
expect(commandPanel.hasParent()).toBeTruthy()
describe "when the mini editor is focused", ->
- it "retains focus on the mini editor and does not show the preview list", ->
+ it "retains focus on the mini editor and does not show the preview list or preview count", ->
expect(commandPanel.miniEditor.isFocused).toBeTruthy()
rootView.trigger 'command-panel:toggle-preview'
expect(commandPanel.previewList).toBeHidden()
+ expect(commandPanel.previewCount).toBeHidden()
expect(commandPanel.miniEditor.isFocused).toBeTruthy()
describe "when the mini editor is not focused", ->
- it "focuses the mini editor and does not show the preview list", ->
+ it "focuses the mini editor and does not show the preview list or preview count", ->
rootView.focus()
rootView.trigger 'command-panel:toggle-preview'
expect(commandPanel.previewList).toBeHidden()
+ expect(commandPanel.previewCount).toBeHidden()
expect(commandPanel.miniEditor.isFocused).toBeTruthy()
describe "when the command panel is not visible", ->
@@ -297,7 +299,7 @@ describe "CommandPanel", ->
expect(commandPanel.previewList).toBeVisible()
expect(commandPanel.previewList).toMatchSelector ':focus'
previewItem = commandPanel.previewList.find("li:contains(sample.js):first")
- expect(previewItem.text()).toBe "sample.js"
+ expect(previewItem.text()).toBe "sample.js(1)"
expect(previewItem.next().find('.preview').text()).toBe "var quicksort = function () {"
expect(previewItem.next().find('.preview > .match').text()).toBe "quicksort"
@@ -377,6 +379,10 @@ describe "CommandPanel", ->
rootView.trigger 'command-panel:toggle'
waitsForPromise -> commandPanel.execute('X x/sort/')
+ it "displays the number of files and operations", ->
+ rootView.attachToDom()
+ expect(commandPanel.previewCount.text()).toBe '17 matches in 4 files'
+
describe "when move-down and move-up are triggered on the preview list", ->
it "selects the next/previous operation (if there is one), and scrolls the list if needed", ->
rootView.attachToDom()
@@ -405,28 +411,15 @@ describe "CommandPanel", ->
previewList.trigger 'core:move-down'
expect(previewList.scrollTop()).toBe 0
- it "wraps around when the list is at the beginning or end", ->
- rootView.attachToDom()
- expect(previewList.find('li.operation:eq(0)')).toHaveClass 'selected'
- expect(previewList.getSelectedOperation()).toBe previewList.getOperations()[0]
-
- previewList.trigger 'core:move-up'
- expect(previewList.find('li.operation:last')).toHaveClass 'selected'
- expect(previewList.getSelectedOperation()).toBe _.last(previewList.getOperations())
-
- previewList.trigger 'core:move-down'
- expect(previewList.find('li.operation:eq(0)')).toHaveClass 'selected'
- expect(previewList.getSelectedOperation()).toBe previewList.getOperations()[0]
-
it "doesn't bubble up the event and the command panel text doesn't change", ->
rootView.attachToDom()
commandPanel.miniEditor.setText "command"
previewList.focus()
previewList.trigger 'core:move-up'
- expect(previewList.find('li.operation:last')).toHaveClass 'selected'
+ expect(previewList.find('li.operation:eq(0)')).toHaveClass 'selected'
expect(commandPanel.miniEditor.getText()).toBe 'command'
previewList.trigger 'core:move-down'
- expect(previewList.find('li.operation:eq(0)')).toHaveClass 'selected'
+ expect(previewList.find('li.operation:eq(1)')).toHaveClass 'selected'
expect(commandPanel.miniEditor.getText()).toBe 'command'
describe "when move-to-top and move-to-bottom are triggered on the preview list", ->
diff --git a/src/packages/command-panel/src/command-panel-view.coffee b/src/packages/command-panel/src/command-panel-view.coffee
index 5e212440c..7ccb74a48 100644
--- a/src/packages/command-panel/src/command-panel-view.coffee
+++ b/src/packages/command-panel/src/command-panel-view.coffee
@@ -24,6 +24,7 @@ class CommandPanelView extends View
@content: (rootView) ->
@div class: 'command-panel tool-panel', =>
+ @div outlet: 'previewCount', class: 'preview-count'
@subview 'previewList', new PreviewList(rootView)
@ul class: 'error-messages', outlet: 'errorMessages'
@div class: 'prompt-and-editor', =>
@@ -48,6 +49,7 @@ class CommandPanelView extends View
@command 'core:move-down', => @navigateForwardInHistory()
@previewList.hide()
+ @previewCount.hide()
@errorMessages.hide()
@prompt.iconSize(@miniEditor.fontSize)
@@ -73,12 +75,14 @@ class CommandPanelView extends View
togglePreview: ->
if @previewList.is(':focus')
@previewList.hide()
+ @previewCount.hide()
@detach()
@rootView.focus()
else
@attach() unless @hasParent()
if @previewList.hasOperations()
@previewList.show().focus()
+ @previewCount.show()
else
@miniEditor.focus()
@@ -94,6 +98,7 @@ class CommandPanelView extends View
detach: ->
@rootView.focus()
@previewList.hide()
+ @previewCount.hide()
super
escapedCommand: ->
@@ -115,6 +120,7 @@ class CommandPanelView extends View
else if operationsToPreview?.length
@previewList.populate(operationsToPreview)
@previewList.focus()
+ @previewCount.text("#{_.pluralize(operationsToPreview.length, 'match', 'matches')} in #{_.pluralize(@previewList.getPathCount(), 'file')}").show()
else
@detach()
catch error
diff --git a/src/packages/command-panel/src/preview-list.coffee b/src/packages/command-panel/src/preview-list.coffee
index 44280eac5..34cbd240c 100644
--- a/src/packages/command-panel/src/preview-list.coffee
+++ b/src/packages/command-panel/src/preview-list.coffee
@@ -34,7 +34,9 @@ class PreviewList extends ScrollView
operation.index = index for operation, index in operations
operationsByPath = _.groupBy(operations, (operation) -> operation.getPath())
for path, ops of operationsByPath
- @li path, class: 'path'
+ @li class: 'path', =>
+ @span path
+ @span "(#{ops.length})", class: 'path-match-number'
for operation in ops
{prefix, suffix, match, range} = operation.preview()
@li 'data-index': operation.index, class: 'operation', =>
@@ -56,16 +58,10 @@ class PreviewList extends ScrollView
lineNumbers.width(maxWidth)
selectNextOperation: ->
- if @selectedOperationIndex is @operations.length - 1
- @setSelectedOperationIndex(0)
- else
- @setSelectedOperationIndex(@selectedOperationIndex + 1)
+ @setSelectedOperationIndex(@selectedOperationIndex + 1)
selectPreviousOperation: ->
- if @selectedOperationIndex is 0
- @setSelectedOperationIndex(@operations.length - 1)
- else
- @setSelectedOperationIndex(@selectedOperationIndex - 1)
+ @setSelectedOperationIndex(@selectedOperationIndex - 1)
setSelectedOperationIndex: (index, scrollToOperation=true) ->
index = Math.max(0, index)
@@ -90,6 +86,9 @@ class PreviewList extends ScrollView
@rootView.focus()
false
+ getPathCount: ->
+ _.keys(_.groupBy(@operations, (operation) -> operation.getPath())).length
+
getOperations: ->
new Array(@operations...)
diff --git a/src/packages/gists/index.coffee b/src/packages/gists/index.coffee
new file mode 100644
index 000000000..6205cb366
--- /dev/null
+++ b/src/packages/gists/index.coffee
@@ -0,0 +1,12 @@
+DeferredAtomPackage = require 'deferred-atom-package'
+
+module.exports =
+class GistsPackage extends DeferredAtomPackage
+
+ loadEvents:
+ 'gist:create': '.editor'
+
+ instanceClass: 'gists/lib/gists'
+
+ onLoadEvent: (event, instance) ->
+ instance.createGist(event.currentTargetView())
diff --git a/src/packages/gists/keymaps/gists.cson b/src/packages/gists/keymaps/gists.cson
new file mode 100644
index 000000000..fa7699100
--- /dev/null
+++ b/src/packages/gists/keymaps/gists.cson
@@ -0,0 +1,2 @@
+'body':
+ 'alt-meta-g': 'gist:create'
diff --git a/src/packages/gists/lib/gists.coffee b/src/packages/gists/lib/gists.coffee
new file mode 100644
index 000000000..434603636
--- /dev/null
+++ b/src/packages/gists/lib/gists.coffee
@@ -0,0 +1,31 @@
+$ = require 'jquery'
+{$$} = require 'space-pen'
+
+module.exports =
+class Gists
+
+ @activate: (rootView) -> new Gists(rootView)
+
+ constructor: (@rootView) ->
+
+ createGist: (editor) ->
+ gist = { public: false, files: {} }
+ gist.files[editor.getBuffer().getBaseName()] =
+ content: editor.getSelectedText() or editor.getText()
+
+ $.ajax
+ url: 'https://api.github.com/gists'
+ type: 'POST'
+ dataType: 'json'
+ contentType: 'application/json; charset=UTF-8'
+ data: JSON.stringify(gist)
+ success: (response) =>
+ pasteboard.write(response.html_url)
+ notification = $$ ->
+ @div class: 'gist-notification', =>
+ @div class: 'message-area', =>
+ @span "Gist #{response.id} created", class: 'message'
+ @br()
+ @span "The url is on your clipboard", class: 'clipboard'
+ @rootView.append(notification.hide())
+ notification.fadeIn().delay(2000).fadeOut(complete: -> $(this).remove())
diff --git a/src/packages/gists/spec/gists-spec.coffee b/src/packages/gists/spec/gists-spec.coffee
new file mode 100644
index 000000000..64227744a
--- /dev/null
+++ b/src/packages/gists/spec/gists-spec.coffee
@@ -0,0 +1,61 @@
+RootView = require 'root-view'
+$ = require 'jquery'
+
+describe "Gists package", ->
+
+ [rootView, editor] = []
+
+ beforeEach ->
+ rootView = new RootView(fixturesProject.resolve('sample.js'))
+ atom.loadPackage('gists').getInstance()
+ editor = rootView.getActiveEditor()
+ spyOn($, 'ajax')
+
+ afterEach ->
+ rootView.deactivate()
+
+ describe "when gist:create is triggered on an editor", ->
+
+ describe "when the editor has no selection", ->
+ [request, originalFxOffValue] = []
+
+ beforeEach ->
+ originalFxOffValue = $.fx.off
+ $.fx.off = true
+ editor.trigger 'gist:create'
+ expect($.ajax).toHaveBeenCalled()
+ request = $.ajax.argsForCall[0][0]
+
+ afterEach ->
+ $.fx.off = originalFxOffValue
+
+ it "creates an Ajax request to api.github.com with the entire buffer contents as the Gist's content", ->
+ expect(request.url).toBe 'https://api.github.com/gists'
+ expect(request.type).toBe 'POST'
+ requestData = JSON.parse(request.data)
+ expect(requestData.public).toBeFalsy()
+ expect(requestData.files).toEqual 'sample.js': content: editor.getText()
+
+ describe "when the server responds successfully", ->
+ beforeEach ->
+ request.success(html_url: 'https://gist.github.com/1', id: '1')
+
+ it "places the created Gist's URL on the clipboard", ->
+ expect(pasteboard.read()[0]).toBe 'https://gist.github.com/1'
+
+ it "flashes that the Gist was created", ->
+ expect(rootView.find('.gist-notification')).toExist()
+ expect(rootView.find('.gist-notification .message').text()).toBe 'Gist 1 created'
+ advanceClock(2000)
+ expect(rootView.find('.gist-notification')).not.toExist()
+
+ describe "when the editor has a selection", ->
+ beforeEach ->
+ editor.setSelectedBufferRange [[4, 0], [8, 0]]
+
+ it "creates an Ajax with the selected text as the Gist's content", ->
+ editor.trigger 'gist:create'
+ expect($.ajax).toHaveBeenCalled()
+ request = $.ajax.argsForCall[0][0]
+ requestData = JSON.parse(request.data)
+ expect(requestData.files).toEqual 'sample.js': content: editor.getSelectedText()
diff --git a/src/packages/go-to-line/index.coffee b/src/packages/go-to-line/index.coffee
new file mode 100644
index 000000000..12601c00e
--- /dev/null
+++ b/src/packages/go-to-line/index.coffee
@@ -0,0 +1,12 @@
+DeferredAtomPackage = require 'deferred-atom-package'
+
+module.exports =
+class GoToLinePackage extends DeferredAtomPackage
+
+ loadEvents:
+ 'editor:go-to-line': '.editor'
+
+ instanceClass: 'go-to-line/lib/go-to-line-view'
+
+ onLoadEvent: (event, instance) ->
+ instance.toggle(event.currentTargetView())
diff --git a/src/packages/go-to-line/keymaps/go-to-line.cson b/src/packages/go-to-line/keymaps/go-to-line.cson
new file mode 100644
index 000000000..5686829bd
--- /dev/null
+++ b/src/packages/go-to-line/keymaps/go-to-line.cson
@@ -0,0 +1,6 @@
+'body':
+ 'meta-l': 'editor:go-to-line'
+'.go-to-line .mini.editor input':
+ 'enter': 'core:confirm',
+ 'escape': 'core:cancel'
+ 'meta-w': 'core:cancel'
diff --git a/src/packages/go-to-line/lib/go-to-line-view.coffee b/src/packages/go-to-line/lib/go-to-line-view.coffee
new file mode 100644
index 000000000..ce99ece31
--- /dev/null
+++ b/src/packages/go-to-line/lib/go-to-line-view.coffee
@@ -0,0 +1,54 @@
+{View} = require 'space-pen'
+Editor = require 'editor'
+$ = require 'jquery'
+Point = require 'point'
+
+module.exports =
+class GoToLineView extends View
+
+ @activate: (rootView) -> new GoToLineView(rootView)
+
+ @content: ->
+ @div class: 'go-to-line', =>
+ @subview 'miniEditor', new Editor(mini: true)
+ @div class: 'message', outlet: 'message'
+
+ initialize: (@rootView) ->
+ @miniEditor.on 'focusout', => @detach()
+ @on 'core:confirm', => @confirm()
+ @on 'core:cancel', => @detach()
+
+ @miniEditor.preempt 'textInput', (e) =>
+ false unless e.originalEvent.data.match(/[0-9]/)
+
+ toggle: ->
+ if @hasParent()
+ @detach()
+ else
+ @attach()
+
+ detach: ->
+ return unless @hasParent()
+
+ @miniEditor.setText('')
+ @previouslyFocusedElement?.focus()
+
+ super
+
+ confirm: ->
+ lineNumber = @miniEditor.getText()
+ editor = rootView.getActiveEditor()
+
+ @detach()
+
+ return unless editor and lineNumber.length
+ position = new Point(parseInt(lineNumber - 1, 0))
+ editor.scrollToBufferPosition(position, center: true)
+ editor.setCursorBufferPosition(position)
+ editor.moveCursorToFirstCharacterOfLine()
+
+ attach: ->
+ @previouslyFocusedElement = $(':focus')
+ @rootView.append(this)
+ @message.text("Enter a line number 1-#{@rootView.getActiveEditor().getLineCount()}")
+ @miniEditor.focus()
diff --git a/src/packages/go-to-line/spec/go-to-line-spec.coffee b/src/packages/go-to-line/spec/go-to-line-spec.coffee
new file mode 100644
index 000000000..775bde131
--- /dev/null
+++ b/src/packages/go-to-line/spec/go-to-line-spec.coffee
@@ -0,0 +1,51 @@
+RootView = require 'root-view'
+
+describe 'GoToLine', ->
+ [rootView, goToLine, editor] = []
+
+ beforeEach ->
+ rootView = new RootView(require.resolve('fixtures/sample.js'))
+ rootView.enableKeymap()
+ goToLine = atom.loadPackage("go-to-line").getInstance()
+ editor = rootView.getActiveEditor()
+ editor.setCursorBufferPosition([1,0])
+
+ afterEach ->
+ rootView.remove()
+
+ describe "when editor:go-to-line is triggered", ->
+ it "attaches to the root view", ->
+ expect(goToLine.hasParent()).toBeFalsy()
+ editor.trigger 'editor:go-to-line'
+ expect(goToLine.hasParent()).toBeTruthy()
+
+ describe "when entering a line number", ->
+ it "only allows 0-9 to be entered in the mini editor", ->
+ expect(goToLine.miniEditor.getText()).toBe ''
+ goToLine.miniEditor.textInput 'a'
+ expect(goToLine.miniEditor.getText()).toBe ''
+ goToLine.miniEditor.textInput '40'
+ expect(goToLine.miniEditor.getText()).toBe '40'
+
+ describe "when core:confirm is triggered", ->
+ describe "when a line number has been entered", ->
+ it "moves the cursor to the first character of the line", ->
+ goToLine.miniEditor.textInput '3'
+ goToLine.miniEditor.trigger 'core:confirm'
+ expect(editor.getCursorBufferPosition()).toEqual [2, 4]
+
+ describe "when no line number has been entered", ->
+ it "closes the view and does not update the cursor position", ->
+ editor.trigger 'editor:go-to-line'
+ expect(goToLine.hasParent()).toBeTruthy()
+ goToLine.miniEditor.trigger 'core:confirm'
+ expect(goToLine.hasParent()).toBeFalsy()
+ expect(editor.getCursorBufferPosition()).toEqual [1, 0]
+
+ describe "when core:cancel is triggered", ->
+ it "closes the view and does not update the cursor position", ->
+ editor.trigger 'editor:go-to-line'
+ expect(goToLine.hasParent()).toBeTruthy()
+ goToLine.miniEditor.trigger 'core:cancel'
+ expect(goToLine.hasParent()).toBeFalsy()
+ expect(editor.getCursorBufferPosition()).toEqual [1, 0]
diff --git a/src/packages/markdown-preview/spec/markdown-preview-spec.coffee b/src/packages/markdown-preview/spec/markdown-preview-spec.coffee
index 575990c57..4ef0efd5a 100644
--- a/src/packages/markdown-preview/spec/markdown-preview-spec.coffee
+++ b/src/packages/markdown-preview/spec/markdown-preview-spec.coffee
@@ -57,3 +57,16 @@ describe "MarkdownPreview", ->
expect(markdownPreviewView).toExist()
markdownPreviewView.trigger('core:cancel')
expect(rootView.find('.markdown-preview')).not.toExist()
+
+ describe "when focus is lost", ->
+ it "removes the markdown preview view", ->
+ rootView.open('file.md')
+ editor = rootView.getActiveEditor()
+ expect(rootView.find('.markdown-preview')).not.toExist()
+ spyOn(markdownPreview, 'loadHtml')
+ editor.trigger('markdown-preview:toggle')
+
+ markdownPreviewView = rootView.find('.markdown-preview')
+ expect(markdownPreviewView).toExist()
+ markdownPreviewView.blur()
+ expect(rootView.find('.markdown-preview')).not.toExist()
diff --git a/src/packages/markdown-preview/src/markdown-preview-view.coffee b/src/packages/markdown-preview/src/markdown-preview-view.coffee
index d7fb9fc6c..914ba8e07 100644
--- a/src/packages/markdown-preview/src/markdown-preview-view.coffee
+++ b/src/packages/markdown-preview/src/markdown-preview-view.coffee
@@ -14,7 +14,9 @@ class MarkdownPreviewView extends ScrollView
initialize: (@rootView) ->
super
- @command 'core:cancel', => @detach()
+
+ @command 'core:cancel', => @detach() unless @detaching
+ @on 'focusout', => @detach() unless @detaching
toggle: ->
if @hasParent()
@@ -30,8 +32,10 @@ class MarkdownPreviewView extends ScrollView
@focus()
detach: ->
- super()
+ @detaching = true
+ super
@rootView.focus()
+ @detaching = false
getActivePath: ->
@rootView.getActiveEditor()?.getPath()
diff --git a/src/packages/symbols-view/index.coffee b/src/packages/symbols-view/index.coffee
index c025f58f0..50d9a89c0 100644
--- a/src/packages/symbols-view/index.coffee
+++ b/src/packages/symbols-view/index.coffee
@@ -6,7 +6,7 @@ class Symbols extends DeferredAtomPackage
loadEvents: [
'symbols-view:toggle-file-symbols'
'symbols-view:toggle-project-symbols'
- 'symbols-view:jump-to-declaration'
+ 'symbols-view:go-to-declaration'
]
instanceClass: 'symbols-view/src/symbols-view'
@@ -17,5 +17,5 @@ class Symbols extends DeferredAtomPackage
instance.toggleFileSymbols()
when 'symbols-view:toggle-project-symbols'
instance.toggleProjectSymbols()
- when 'symbols-view:jump-to-declaration'
- instance.jumpToDeclaration()
+ when 'symbols-view:go-to-declaration'
+ instance.goToDeclaration()
diff --git a/src/packages/symbols-view/keymaps/symbols-view.cson b/src/packages/symbols-view/keymaps/symbols-view.cson
index 4a77be68d..1e579abe0 100644
--- a/src/packages/symbols-view/keymaps/symbols-view.cson
+++ b/src/packages/symbols-view/keymaps/symbols-view.cson
@@ -1,6 +1,6 @@
'.editor':
'meta-j': 'symbols-view:toggle-file-symbols'
- 'meta-.': 'symbols-view:jump-to-declaration'
+ 'meta-.': 'symbols-view:go-to-declaration'
'body':
'meta-J': 'symbols-view:toggle-project-symbols'
diff --git a/src/packages/symbols-view/spec/symbols-view-spec.coffee b/src/packages/symbols-view/spec/symbols-view-spec.coffee
index 9bfe907bd..89476c8d5 100644
--- a/src/packages/symbols-view/spec/symbols-view-spec.coffee
+++ b/src/packages/symbols-view/spec/symbols-view-spec.coffee
@@ -126,26 +126,26 @@ describe "SymbolsView", ->
generator.generate().done ->
expect(tags.length).toBe 0
- describe "jump to declaration", ->
+ describe "go to declaration", ->
it "doesn't move the cursor when no declaration is found", ->
rootView.open("tagged.js")
editor = rootView.getActiveEditor()
editor.setCursorBufferPosition([0,2])
- editor.trigger 'symbols-view:jump-to-declaration'
+ editor.trigger 'symbols-view:go-to-declaration'
expect(editor.getCursorBufferPosition()).toEqual [0,2]
it "moves the cursor to the declaration", ->
rootView.open("tagged.js")
editor = rootView.getActiveEditor()
editor.setCursorBufferPosition([6,24])
- editor.trigger 'symbols-view:jump-to-declaration'
+ editor.trigger 'symbols-view:go-to-declaration'
expect(editor.getCursorBufferPosition()).toEqual [2,0]
it "displays matches when more than one exists and opens the selected match", ->
rootView.open("tagged.js")
editor = rootView.getActiveEditor()
editor.setCursorBufferPosition([8,14])
- editor.trigger 'symbols-view:jump-to-declaration'
+ editor.trigger 'symbols-view:go-to-declaration'
expect(symbolsView.list.children('li').length).toBe 2
expect(symbolsView).toBeVisible()
symbolsView.confirmed(symbolsView.array[0])
@@ -163,7 +163,7 @@ describe "SymbolsView", ->
rootView.open("tagged.js")
editor = rootView.getActiveEditor()
editor.setCursorBufferPosition([8,14])
- editor.trigger 'symbols-view:jump-to-declaration'
+ editor.trigger 'symbols-view:go-to-declaration'
expect(symbolsView.list.children('li').length).toBe 1
expect(symbolsView.list.children('li:first').find('.function-name')).toHaveText 'tagged.js'
diff --git a/src/packages/symbols-view/src/symbols-view.coffee b/src/packages/symbols-view/src/symbols-view.coffee
index afcd5109e..c0d019132 100644
--- a/src/packages/symbols-view/src/symbols-view.coffee
+++ b/src/packages/symbols-view/src/symbols-view.coffee
@@ -102,7 +102,7 @@ class SymbolsView extends SelectList
for line, index in fs.read(file).split('\n')
return new Point(index, 0) if pattern is $.trim(line)
- jumpToDeclaration: ->
+ goToDeclaration: ->
editor = @rootView.getActiveEditor()
matches = TagReader.find(editor)
return unless matches.length
diff --git a/src/packages/tabs/stylesheets/tabs.css b/src/packages/tabs/stylesheets/tabs.css
index 0239bc734..ebdfad7f2 100644
--- a/src/packages/tabs/stylesheets/tabs.css
+++ b/src/packages/tabs/stylesheets/tabs.css
@@ -1,14 +1,20 @@
.tabs {
-webkit-user-select: none;
+ display: -webkit-box;
+ -webkit-box-align: center;
}
.tab {
- display: table-cell;
+ -webkit-box-flex: 2;
position: relative;
- width:175px;
+ width: 175px;
+ max-width: 175px;
min-width: 40px;
box-sizing: border-box;
- height: 24px;
+}
+
+.tab.active {
+ -webkit-box-flex: 1;
}
.tab.file-modified .close-icon {
@@ -23,9 +29,5 @@
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
- position: absolute;
- left: 9px;
- top:4px;
- bottom:4px;
- right: 21px;
+ padding: 3px 5px;
}
\ No newline at end of file
diff --git a/themes/Atom - Dark/command-panel.css b/themes/Atom - Dark/command-panel.css
index 8f4a6e405..dfc7f225b 100644
--- a/themes/Atom - Dark/command-panel.css
+++ b/themes/Atom - Dark/command-panel.css
@@ -15,6 +15,13 @@
cursor: default;
}
+.command-panel .preview-count {
+ font-size: 11px;
+ color: #969696;
+ text-align: right;
+ padding-bottom: 1px;
+}
+
.command-panel .preview-list li.selected, .command-panel .preview-list li.operation:hover {
background-color: rgba(255, 255, 255, .13);
}
@@ -53,6 +60,11 @@
display: inline-block;
}
+.command-panel .preview-list .path-match-number {
+ padding-left: 8px;
+ color: rgba(255, 255, 255, .3);
+}
+
.command-panel .preview-list .preview {
word-break: break-all;
}
diff --git a/themes/Atom - Dark/gists.css b/themes/Atom - Dark/gists.css
new file mode 100644
index 000000000..dde2dbd25
--- /dev/null
+++ b/themes/Atom - Dark/gists.css
@@ -0,0 +1,35 @@
+.gist-notification {
+ position: absolute;
+ top: 6px;
+ left: 50%;
+ margin-left: -5%;
+ z-index: 99;
+ padding-left: 5px;
+ padding-right: 10px;
+ -webkit-box-shadow: 0px 0px 5px 5px #222;
+ color: #BBB;
+ background-color: #333;
+}
+
+.gist-notification .message-area {
+ float: right;
+ padding-top: 11px;
+}
+
+.gist-notification .message {
+ font-size: 13px;
+}
+
+.gist-notification .clipboard {
+ font-size: 11px;
+}
+
+.gist-notification:before {
+ font-family: 'Octicons Regular';
+ font-size: 32px;
+ width: 32px;
+ height: 32px;
+ margin-right: 5px;
+ -webkit-font-smoothing: antialiased;
+ content: "\f08c";
+}
diff --git a/themes/Atom - Dark/go-to-line.css b/themes/Atom - Dark/go-to-line.css
new file mode 100644
index 000000000..4ceec81aa
--- /dev/null
+++ b/themes/Atom - Dark/go-to-line.css
@@ -0,0 +1,27 @@
+.go-to-line {
+ position: absolute;
+ width: 200px;
+ top: 0;
+ left: 50%;
+ margin-left: -100px;
+ box-sizing: border-box;
+ z-index: 99;
+ background-color: #484848;
+ border: 1px solid #444;
+ color: #d2d2d2;
+ box-shadow: 0 0 10px #000;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ padding: 5px;
+ cursor: pointer;
+}
+
+.go-to-line .editor {
+ box-sizing: border-box;
+ padding: 5px;
+}
+
+.go-to-line .message {
+ padding-top: 2px;
+ font-size: 11px;
+}
diff --git a/themes/Atom - Dark/package.json b/themes/Atom - Dark/package.json
index 4d5c95b40..28f90e051 100644
--- a/themes/Atom - Dark/package.json
+++ b/themes/Atom - Dark/package.json
@@ -14,6 +14,8 @@
"command-panel.css",
"command-palette.css",
"command-logger.css",
- "autocomplete.css"
+ "autocomplete.css",
+ "gists.css",
+ "go-to-line.css"
]
}
diff --git a/themes/Atom - Dark/tabs.css b/themes/Atom - Dark/tabs.css
index 732a5c3aa..09942bec6 100644
--- a/themes/Atom - Dark/tabs.css
+++ b/themes/Atom - Dark/tabs.css
@@ -61,7 +61,7 @@
.tab.active:hover {
border-top: 1px solid #4a4a4a;
box-shadow: inset -1px 0 0 #595959, inset 1px 0 0 #595959;
- border-bottom: 0 none;
+ border-bottom-color: #424242;
background-image: -webkit-linear-gradient(#555555, #424242);
}
diff --git a/themes/Atom - Light/command-panel.css b/themes/Atom - Light/command-panel.css
index 5344b859d..4bfff1d22 100644
--- a/themes/Atom - Light/command-panel.css
+++ b/themes/Atom - Light/command-panel.css
@@ -16,6 +16,13 @@
border: 1px solid #989898;
}
+.command-panel .preview-count {
+ font-size: 11px;
+ color: #333;
+ text-align: right;
+ padding-bottom: 1px;
+}
+
.command-panel .preview-list li.selected, .command-panel .preview-list li.operation:hover {
background-color: rgba(255, 255, 255, .6);
}
@@ -50,6 +57,11 @@
display: inline-block;
}
+.command-panel .preview-list .path-match-number {
+ padding-left: 8px;
+ color: #3D5075;
+}
+
.command-panel .preview-list .preview {
word-break: break-all;
}
diff --git a/themes/Atom - Light/gists.css b/themes/Atom - Light/gists.css
new file mode 100644
index 000000000..0209ce3e3
--- /dev/null
+++ b/themes/Atom - Light/gists.css
@@ -0,0 +1,35 @@
+.gist-notification {
+ position: absolute;
+ top: 6px;
+ left: 50%;
+ margin-left: -5%;
+ z-index: 99;
+ padding-left: 5px;
+ padding-right: 10px;
+ -webkit-box-shadow: 0px 0px 5px 5px #222;
+ color: #BBB;
+ background-color: #444;
+}
+
+.gist-notification .message-area {
+ float: right;
+ padding-top: 11px;
+}
+
+.gist-notification .message {
+ font-size: 13px;
+}
+
+.gist-notification .clipboard {
+ font-size: 11px;
+}
+
+.gist-notification:before {
+ font-family: 'Octicons Regular';
+ font-size: 32px;
+ width: 32px;
+ height: 32px;
+ margin-right: 5px;
+ -webkit-font-smoothing: antialiased;
+ content: "\f08c";
+}
diff --git a/themes/Atom - Light/go-to-line.css b/themes/Atom - Light/go-to-line.css
new file mode 100644
index 000000000..9f6c3ec8b
--- /dev/null
+++ b/themes/Atom - Light/go-to-line.css
@@ -0,0 +1,27 @@
+.go-to-line {
+ position: absolute;
+ width: 200px;
+ top: 0;
+ left: 50%;
+ margin-left: -100px;
+ box-sizing: border-box;
+ z-index: 99;
+ background-color: #eeeeee;
+ border: 1px solid #c6c6c6;
+ color: #323232;
+ box-shadow: 0 0 10px #555;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ padding: 5px;
+ cursor: pointer;
+}
+
+.go-to-line .editor {
+ box-sizing: border-box;
+ padding: 5px;
+}
+
+.go-to-line .message {
+ padding-top: 2px;
+ font-size: 11px;
+}
diff --git a/themes/Atom - Light/package.json b/themes/Atom - Light/package.json
index 4d5c95b40..28f90e051 100644
--- a/themes/Atom - Light/package.json
+++ b/themes/Atom - Light/package.json
@@ -14,6 +14,8 @@
"command-panel.css",
"command-palette.css",
"command-logger.css",
- "autocomplete.css"
+ "autocomplete.css",
+ "gists.css",
+ "go-to-line.css"
]
}
diff --git a/themes/Atom - Light/tabs.css b/themes/Atom - Light/tabs.css
index 557b00b39..6b286ad61 100644
--- a/themes/Atom - Light/tabs.css
+++ b/themes/Atom - Light/tabs.css
@@ -54,7 +54,7 @@
.tab.active,
.tab.active:hover {
- border-bottom: 0 none;
+ border-bottom-color: #e5e5e5;
box-shadow: inset -1px 0 0 #e0e0e0, inset 1px 0 0 #e0e0e0;
background-image: -webkit-linear-gradient(#fefefe, #e7e6e7);
}
@@ -62,7 +62,7 @@
.tab.active:before,
.tab.active:after {
position: absolute;
- bottom: 0;
+ bottom: -1px;
width: 4px;
height: 4px;
content: " ";