Added atom configuration and setup bindings for mini buff explorer

pull/1/head
Adam Veldhousen 10 years ago
parent ef7d28aa1f
commit 3f787f3031

5
.atom/.gitignore vendored

@ -0,0 +1,5 @@
storage
compile-cache
dev
.npm
.node-gyp

@ -0,0 +1,14 @@
'editor':
'fontSize': 16
'core':
'themes': [
'spacegray-mocha-ui'
'jellybeans'
]
'useReactEditor': true
'exception-reporting':
'userId': '1c9d1b3d-fdb9-e390-da2c-bd840428aa77'
'welcome':
'showOnStartup': false
'metrics':
'userId': 'c4e928ad4b095ae6ca1595c2945c97457bc6fe1f'

@ -0,0 +1,14 @@
# Your init script
#
# Atom will evaluate this file each time a new window is opened. It is run
# after packages are loaded/activated and after the previous editor state
# has been restored.
#
# An example hack to make opened Markdown files always be soft wrapped:
#
# path = require 'path'
#
# atom.workspaceView.eachEditorView (editorView) ->
# editor = editorView.getEditor()
# if path.extname(editor.getPath()) is '.md'
# editor.setSoftWrap(true)

@ -0,0 +1,18 @@
# Your keymap
#
# Atom keymaps work similarly to stylesheets. Just as stylesheets use selectors
# to apply styles to elements, Atom keymaps use selectors to associate
# keystrokes with events in specific contexts.
#
# You can create a new keybinding in this file by typing "key" and then hitting
# tab.
#
# Here's an example taken from Atom's built-in keymap:
#
# '.editor':
# 'enter': 'editor:newline'
#
# '.workspace':
# 'ctrl-P': 'core:move-up'
# 'ctrl-p': 'core:move-down'
#

@ -0,0 +1 @@
All packages in this directory will be automatically loaded

@ -0,0 +1,3 @@
.DS_Store
npm-debug.log
node_modules

@ -0,0 +1,20 @@
Copyright (c) 2014 Karan Goel
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,9 @@
# atom-terminal
Open terminal on current file's directory with `ctrl-shift-t`.
Keybinding: `ctrl-shift-t`
Install: `apm install atom-terminal`
![atom-terminal](https://raw.github.com/karan/atom-terminal/master/terminal.gif)

@ -0,0 +1,11 @@
# Keybindings require three things to be fully defined: A selector that is
# matched against the focused element, the keystroke and the command to
# execute.
#
# Below is a basic keybinding which registers on all platforms by applying to
# the root workspace element.
# For more detailed documentation see
# https://atom.io/docs/latest/advanced/keymaps
'.workspace':
'ctrl-shift-t': 'atom-terminal:open'

@ -0,0 +1,75 @@
exec = require('child_process').exec
path = require('path')
platform = require('os').platform
###
Opens a terminal in the given directory, as specefied by the config
###
open_terminal = (dirpath) ->
# Figure out the app and the arguments
app = atom.config.get('atom-terminal.app')
args = atom.config.get('atom-terminal.args')
# get options
setWorkingDirectory = atom.config.get('atom-terminal.setWorkingDirectory')
surpressDirArg = atom.config.get('atom-terminal.surpressDirectoryArgument')
runDirectly = atom.config.get('atom-terminal.MacWinRunDirectly')
# Start assembling the command line
cmdline = "#{app} #{args}"
# If we do not supress the directory argument, add the directory as an argument
if !surpressDirArg
cmdline += "\"#{dirpath}\""
# For mac, we prepend open -a unless we run it directly
if platform() == "darwin" && !runDirectly
cmdline = "open -a " + cmdline
# for windows, we prepend start unless we run it directly.
if platform() == "win32" && !runDirectly
cmdline = "start " + cmdline
# Set the working directory if configured
if setWorkingDirectory
exec cmdline, cwd: dirpath if dirpath?
else
exec cmdline if dirpath?
module.exports =
activate: ->
atom.workspaceView.command "atom-terminal:open", => @open()
open: ->
filepath = atom.workspaceView.find('.tree-view .selected')?.view()?.getPath?()
if filepath
open_terminal path.dirname(filepath)
# Set per-platform defaults
if platform() == 'darwin'
# Defaults for Mac, use Terminal.app
module.exports.configDefaults = {
app: 'Terminal.app'
args: ''
surpressDirectoryArgument: false
setWorkingDirectory: false
MacWinRunDirectly: false
}
else if platform() == 'win32'
# Defaults for windows, use cmd.exe as default
module.exports.configDefaults = {
app: 'C:\\Windows\\System32\\cmd.exe'
args: ''
surpressDirectoryArgument: false
setWorkingDirectory: true
MacWinRunDirectly: false
}
else
# Defaults for all other systems (linux I assume), use xterm
module.exports.configDefaults = {
app: '/usr/bin/xterm'
args: ''
surpressDirectoryArgument: true
setWorkingDirectory: true
MacWinRunDirectly: false
}

@ -0,0 +1,30 @@
{
"name": "atom-terminal",
"main": "./lib/atom-terminal",
"version": "0.4.0",
"description": "Open terminal in the current file's directory.",
"activationEvents": [
"atom-terminal:open"
],
"repository": {
"type": "git",
"url": "https://github.com/karan/atom-terminal"
},
"license": "MIT",
"engines": {
"atom": ">0.50.0"
},
"dependencies": {},
"readme": "# atom-terminal\n\nOpen terminal on current file's directory with `ctrl-shift-t`.\n\nKeybinding: `ctrl-shift-t`\n\nInstall: `apm install atom-terminal`\n\n![atom-terminal](https://raw.github.com/karan/atom-terminal/master/terminal.gif)\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/karan/atom-terminal/issues"
},
"homepage": "https://github.com/karan/atom-terminal",
"_id": "atom-terminal@0.4.0",
"dist": {
"shasum": "3a99b5a114f131327a109c891e5d684ad4364cdb"
},
"_resolved": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114614-2816-1jjfr4z\\package.tgz",
"_from": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114614-2816-1jjfr4z\\package.tgz"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 885 KiB

@ -0,0 +1,3 @@
.DS_Store
npm-debug.log
node_modules

@ -0,0 +1,20 @@
Copyright (c) 2014 Thomas Lindstrøm
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,18 @@
# A Color Picker for Atom
A color picker for Atom. Either right click a color and select `Color picker`, or hit `CMD-SHIFT-C`/`CTRL-ALT-C` anywhere. Currently reads HEX, HEXA, RGB, RGBA, HSL and HSLA.
Inspects Sass/LESS variables! [Take a look here.](http://t.hom.as/colorpicker4.mov)
**NEW:** You can now open the color picker whenever, without input, using `CMD-SHIFT-C`/`CTRL-ALT-C`!
## Preview
![Color Picker in action](http://f.cl.ly/items/3g3T401o0o0F2m2O1z1K/output.gif)
## To do
- Stylus variable lookup
- Context menu convertions
- Preview color manipulation functions (lighten, darken)
- Edit the color value

@ -0,0 +1,14 @@
# Keybindings require three things to be fully defined: A selector that is
# matched against the focused element, the keystroke and the command to
# execute.
#
# Below is a basic keybinding which registers on all platforms by applying to
# the root workspace element.
# For more detailed documentation see
# https://atom.io/docs/latest/advanced/keymaps
'.platform-darwin .workspace':
'cmd-C': 'color-picker:open'
'.platform-win32 .workspace, .platform-linux .workspace':
'ctrl-alt-c': 'color-picker:open'

@ -0,0 +1,31 @@
# ----------------------------------------------------------------------------
# ColorPicker: Alpha selector
# ----------------------------------------------------------------------------
Convert = require './ColorPicker-convert'
$el = atom.workspaceView.find '#ColorPicker-alphaSelector'
$selection = atom.workspaceView.find '#ColorPicker-alphaSelection'
_context = $el[0].getContext '2d'
_width = $el.width()
_height = $el.height()
# -------------------------------------
# Public functionality
# -------------------------------------
module.exports =
$el: $el
$selection: $selection
width: _width
height: _height
# Draw the alpha selector gradient
render: (color) ->
_gradient = _context.createLinearGradient 0, 0, 1, _height
_context.clearRect 0, 0, _width, _height
_rgbString = color.join ', '
_gradient.addColorStop 0, "rgba(#{ _rgbString }, 1)"
_gradient.addColorStop 1, "rgba(#{ _rgbString }, 0)"
_context.fillStyle = _gradient
_context.fillRect 0, 0, _width, _height

@ -0,0 +1,150 @@
# ----------------------------------------------------------------------------
# ColorPicker: Convert
# ----------------------------------------------------------------------------
module.exports =
# -------------------------------------
# HEX to RGB
# -------------------------------------
hexToRgb: (hex) ->
hex = hex.replace '#', ''
if hex.length is 3 then hex = hex.replace /(.)(.)(.)/, "$1$1$2$2$3$3"
return [
(parseInt (hex.substr 0, 2), 16),
(parseInt (hex.substr 2, 2), 16),
(parseInt (hex.substr 4, 2), 16)
]
# -------------------------------------
# HEXA to RGB
# -------------------------------------
hexaToRgb: (hexa) ->
return @hexToRgb (hexa.match /rgba\((\#.+),/)[1]
# -------------------------------------
# HEX to HSL
# -------------------------------------
hexToHsl: (hex) ->
hex = hex.replace '#', ''
return @rgbToHsl @hexToRgb hex
# -------------------------------------
# RGB to HEX
# -------------------------------------
rgbToHex: (rgb) ->
_componentToHex = (component) ->
_hex = component.toString 16
return if _hex.length is 1 then "0#{ _hex }" else _hex
return [
(_componentToHex rgb[0]),
(_componentToHex rgb[1]),
(_componentToHex rgb[2])
].join ''
# -------------------------------------
# RGB to HSL
# -------------------------------------
rgbToHsl: ([r, g, b]) ->
r /= 255
g /= 255
b /= 255
_max = Math.max r, g, b
_min = Math.min r, g, b
_l = (_max + _min) / 2
if _max is _min then return [0, 0, Math.floor _l * 100]
_d = _max - _min
_s = if _l > 0.5 then _d / (2 - _max - _min) else _d / (_max + _min)
switch _max
when r then _h = (g - b) / _d + (if g < b then 6 else 0)
when g then _h = (b - r) / _d + 2
when b then _h = (r - g) / _d + 4
_h /= 6
return [
Math.floor _h * 360
Math.floor _s * 100
Math.floor _l * 100
]
# -------------------------------------
# RGB to HSV
# -------------------------------------
rgbToHsv: (rgb) ->
if typeof rgb is 'string' then rgb = rgb.match /(\d+)/g
[r, g, b] = rgb
computedH = 0
computedS = 0
computedV = 0
#remove spaces from input RGB values, convert to int
r = parseInt(("" + r).replace(/\s/g, ""), 10)
g = parseInt(("" + g).replace(/\s/g, ""), 10)
b = parseInt(("" + b).replace(/\s/g, ""), 10)
if not r? or not g? or not b? or isNaN(r) or isNaN(g) or isNaN(b)
alert "Please enter numeric RGB values!"
return
if r < 0 or g < 0 or b < 0 or r > 255 or g > 255 or b > 255
alert "RGB values must be in the range 0 to 255."
return
r = r / 255
g = g / 255
b = b / 255
minRGB = Math.min(r, Math.min(g, b))
maxRGB = Math.max(r, Math.max(g, b))
# Black-gray-white
if minRGB is maxRGB
computedV = minRGB
return [
0
0
computedV
]
# Colors other than black-gray-white:
d = (if (r is minRGB) then g - b else ((if (b is minRGB) then r - g else b - r)))
h = (if (r is minRGB) then 3 else ((if (b is minRGB) then 1 else 5)))
computedH = 60 * (h - d / (maxRGB - minRGB))
computedS = (maxRGB - minRGB) / maxRGB
computedV = maxRGB
return [
computedH
computedS
computedV
]
# -------------------------------------
# HSV to HSL
# -------------------------------------
hsvToHsl: ([h, s, v]) ->
return [
h,
s * v / (if (h = (2 - s) * v) < 1 then h else 2 - h)
h / 2
]
# -------------------------------------
# HSL to HSV
# -------------------------------------
hslToHsv: ([h, s, l]) ->
s *= if l < .5 then l else 1 - l
return [
h,
2 * s / (l + s)
l + s
]

@ -0,0 +1,38 @@
# ----------------------------------------------------------------------------
# ColorPicker: Hue selector
# ----------------------------------------------------------------------------
Convert = require './ColorPicker-convert'
_hexes = ['FF0000', 'FFFF00', '00FF00', '00FFFF', '0000FF', 'FF00FF', 'FF0000']
$el = atom.workspaceView.find '#ColorPicker-hueSelector'
$selection = atom.workspaceView.find '#ColorPicker-hueSelection'
_context = $el[0].getContext '2d'
_width = $el.width()
_height = $el.height()
# -------------------------------------
# Public functionality
# -------------------------------------
module.exports =
$el: $el
$selection: $selection
width: _width
height: _height
# Draw the hue selector gradient
render: ->
_gradient = _context.createLinearGradient 0, 0, 1, _height
_step = 1 / (_hexes.length - 1)
_gradient.addColorStop (_step * i), hex for hex, i in _hexes
_context.fillStyle = _gradient
_context.fillRect 0, 0, _width, _height
# Returns a color from a position on the canvas
getColorAtPosition: (positionY) ->
_data = (_context.getImageData 1, (positionY - 1), 1, 1).data
return {
color: ('#' + Convert.rgbToHex _data),
type: 'hex'
}

@ -0,0 +1,36 @@
# ----------------------------------------------------------------------------
# ColorPicker: Regexes
# ----------------------------------------------------------------------------
module.exports = [
# Matches Sass variable: eg.
# $color-var
{ type: 'variable:sass', regex: /([\$])([\w0-9-_]+)/ig }
# Matches LESS variable: eg.
# @color-var
{ type: 'variable:less', regex: /([\@])([\w0-9-_]+)/ig }
# Matches HSL + A: eg
# hsla(320, 100%, 38%, 0.3) and hsla(26, 57, 32, .3)
{ type: 'hsla', regex: /hsla\(([0-9]|[1-9][0-9]|[1|2][0-9][0-9]|3[0-5][0-9]|360),\s*([0-9]|[1-9][0-9]|100)\%?,\s*([0-9]|[1-9][0-9]|100)\%?,\s*(0|1|0*\.\d+)\)/ig }
# Matches HSL: eg
# hsl(320, 100%, 38%) and hsl(26, 57, 32)
{ type: 'hsl', regex: /hsl\(([0-9]|[1-9][0-9]|[1|2][0-9][0-9]|3[0-5][0-9]|360),\s*([0-9]|[1-9][0-9]|100)\%?,\s*([0-9]|[1-9][0-9]|100)\%?\)/ig }
# Matches HEX + A: eg
# rgba(#fff, 0.3) and rgba(#000000, .8)
{ type: 'hexa', regex: /(rgba\(((\#[a-f0-9]{6}|\#[a-f0-9]{3}))\s*,\s*(0|1|0*\.\d+)\))/ig }
# Matches RGB + A: eg.
# rgba(0, 99, 199, 0.3)
{ type: 'rgba', regex: /(rgba\(((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\s*,\s*([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\s*,\s*([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])))\s*,\s*(0|1|0*\.\d+)\))/ig }
# Matches RGB: eg.
# rgb(0, 99, 199)
{ type: 'rgb', regex: /(rgb\(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\s*,\s*([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\s*,\s*([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\))/ig }
# Matches HEX:
# eg. #000 and #ffffff
{ type: 'hex', regex: /(\#[a-f0-9]{6}|\#[a-f0-9]{3})/ig }
]

@ -0,0 +1,49 @@
# ----------------------------------------------------------------------------
# ColorPicker: Saturation selector
# ----------------------------------------------------------------------------
Convert = require './ColorPicker-convert'
$el = atom.workspaceView.find '#ColorPicker-saturationSelector'
$selection = atom.workspaceView.find '#ColorPicker-saturationSelection'
_context = $el[0].getContext '2d'
_width = $el.width()
_height = $el.height()
# -------------------------------------
# Public functionality
# -------------------------------------
module.exports =
$el: $el
$selection: $selection
width: _width
height: _height
# Draw the saturation selector
render: (hex) ->
_hsl = Convert.hexToHsl hex
_context.clearRect 0, 0, _width, _height
# Draw the hue channel
_gradient = _context.createLinearGradient 0, 0, _width, 1
_gradient.addColorStop .01, '#fff'
_gradient.addColorStop .99, "hsl(#{ _hsl[0] }, 100%, 50%)"
_context.fillStyle = _gradient
_context.fillRect 0, 0, _width, _height
# Draw the saturation channel
_gradient = _context.createLinearGradient 0, 0, 1, _height
_gradient.addColorStop .01, 'rgba(0, 0, 0, 0)'
_gradient.addColorStop .99, '#000'
_context.fillStyle = _gradient
_context.fillRect 0, 0, _width, _height
# Returns a color from a position on the canvas
getColorAtPosition: (positionX, positionY) ->
_data = (_context.getImageData (positionX - 1), (positionY - 1), 1, 1).data
return {
color: ('#' + Convert.rgbToHex _data),
type: 'hex'
}

@ -0,0 +1,453 @@
# ----------------------------------------------------------------------------
# ColorPicker: View
# ----------------------------------------------------------------------------
{ View } = require 'atom'
Convert = require './ColorPicker-convert'
ColorPicker = null
SaturationSelector = null
HueSelector = null
AlphaSelector = null
module.exports = class ColorPickerView extends View
@content: ->
c = 'ColorPicker-'
@div id: 'ColorPicker', class: 'ColorPicker', =>
@div id: "#{ c }loader", class: "#{ c }loader", =>
@div class: "#{ c }loaderDot"
@div class: "#{ c }loaderDot"
@div class: "#{ c }loaderDot"
@div id: "#{ c }color", class: "#{ c }color", =>
@div id: "#{ c }value", class: "#{ c }value"
@div id: "#{ c }initialWrapper", class: "#{ c }initialWrapper", =>
@div id: "#{ c }initial", class: "#{ c }initial"
@div id: "#{ c }picker", class: "#{ c }picker", =>
@div id: "#{ c }saturationSelectorWrapper", class: "#{ c }saturationSelectorWrapper", =>
@div id: "#{ c }saturationSelection", class: "#{ c }saturationSelection"
@canvas id: "#{ c }saturationSelector", class: "#{ c }saturationSelector", width: '180px', height: '180px'
@div id: "#{ c }alphaSelectorWrapper", class: "#{ c }alphaSelectorWrapper", =>
@div id: "#{ c }alphaSelection", class: "#{ c }alphaSelection"
@canvas id: "#{ c }alphaSelector", class: "#{ c }alphaSelector", width: '20px', height: '180px'
@div id: "#{ c }hueSelectorWrapper", class: "#{ c }hueSelectorWrapper", =>
@div id: "#{ c }hueSelection", class: "#{ c }hueSelection"
@canvas id: "#{ c }hueSelector", class: "#{ c }hueSelector", width: '20px', height: '180px'
initialize: ->
(atom.workspaceView.find '.vertical').append this
ColorPicker = require './ColorPicker'
SaturationSelector = require './ColorPicker-saturationSelector'
AlphaSelector = require './ColorPicker-alphaSelector'
HueSelector = require './ColorPicker-hueSelector'
HueSelector.render()
@bind()
# Tear down any state and detach
destroy: ->
@close()
this.remove()
@detach()
# -------------------------------------
# Controller state storage
# -------------------------------------
storage: {
activeView: null
selectedColor: null
pickedColor: null
saturation: x: 0, y: 0
hue: 0
alpha: 0
}
# -------------------------------------
# Show or hide color picker
# -------------------------------------
isOpen: false
reset: ->
this.addClass 'is--visible is--initial'
this.removeClass 'no--arrow is--pointer is--searching'
(this.find '#ColorPicker-color')
.css 'background-color', ''
.css 'border-bottom-color', ''
(this.find '#ColorPicker-value')
.attr 'data-variable', ''
.html ''
open: ->
@isOpen = true
_selectedColor = @storage.selectedColor
if not _selectedColor or _selectedColor.hasOwnProperty 'pointer'
this.addClass 'is--pointer'
if not _selectedColor then this.addClass 'is--searching'
_colorPickerWidth = this.width()
_colorPickerHeight = this.height()
_halfColorPickerWidth = _colorPickerWidth / 2
_pane = atom.workspaceView.getActivePaneView()
_paneOffset = top: _pane[0].offsetTop, left: _pane[0].offsetLeft
_tabBarHeight = (_pane.find '.tab-bar').height()
@storage.activeView = _view = _pane.activeView
_position = _view.pixelPositionForScreenPosition _view.getEditor().getCursorScreenPosition()
_gutterWidth = (_view.find '.gutter').width()
_scroll = top: _view.scrollTop(), left: _view.scrollLeft()
_scrollbar = _view.verticalScrollbar
if _scrollbar then _scrollbar.on 'scroll.color-picker', => @scroll()
# Add 15 to account for the arrow on top of the color picker
_top = 15 + _position.top - _scroll.top + _view.lineHeight + _tabBarHeight
_left = _position.left - _scroll.left + _gutterWidth
# Make adjustments based on view size: don't let the color picker
# disappear or overflow
_viewWidth = _view.width()
_viewHeight = _view.height()
# Remove 15 to ignore the arrow on top of the color picker
if _top + _colorPickerHeight - 15 > _viewHeight
_top = _viewHeight + _tabBarHeight - _colorPickerHeight - 20
this.addClass 'no--arrow'
_top += _paneOffset.top
if _left + _halfColorPickerWidth > _viewWidth
_left = _viewWidth - _halfColorPickerWidth - 20
this.addClass 'no--arrow'
_left += _paneOffset.left - _halfColorPickerWidth
this # Place the color picker
.css 'top', Math.max 20, _top
.css 'left', Math.max 20, _left
close: ->
@isOpen = false
this.removeClass 'is--visible is--initial is--searching is--error'
return unless @storage.activeView and @storage.activeView.verticalScrollbar
@storage.activeView.verticalScrollbar.off 'scroll.color-picker'
error: ->
@storage.selectedColor = null
this
.removeClass 'is--searching'
.addClass 'is--error'
scroll: -> if @isOpen then @close()
# -------------------------------------
# Bind controls
# -------------------------------------
bind: ->
window.onresize = => if @isOpen then @close()
atom.workspaceView.on 'pane:active-item-changed', => @close()
$body = this.parents 'body'
do => # Bind the color output control
$body.on 'mousedown', (e) =>
_target = e.target
_className = _target.className
# Close unless the click target is something related to
# the color picker
return @close() unless /ColorPicker/.test _className
_color = @storage.selectedColor
switch _className
when 'ColorPicker-color'
if (_color?.hasOwnProperty 'pointer') and _pointer = _color.pointer
(atom.workspace.open _pointer.filePath).finally =>
_editor = atom.workspace.activePaneItem
_editor.clearSelections()
_editor.setSelectedBufferRange _pointer.range
else @replaceColor()
@close()
when 'ColorPicker-initialWrapper'
@inputColor _color
this.addClass 'is--initial'
.on 'keydown', (e) =>
return unless @isOpen
return @close() unless e.which is 13
e.preventDefault()
e.stopPropagation()
@replaceColor()
@close()
do => # Bind the saturation selector controls
_isGrabbingSaturationSelection = false
$body.on 'mousedown mousemove mouseup', (e) =>
_offset = SaturationSelector.$el.offset()
_offsetY = Math.max 1, (Math.min SaturationSelector.height, (e.pageY - _offset.top))
_offsetX = Math.max 1, (Math.min SaturationSelector.width, (e.pageX - _offset.left))
switch e.type
when 'mousedown'
return unless e.target.className is 'ColorPicker-saturationSelector'
e.preventDefault()
_isGrabbingSaturationSelection = true
when 'mousemove'
return unless _isGrabbingSaturationSelection
e.preventDefault()
when 'mouseup'
_isGrabbingSaturationSelection = false
return unless _isGrabbingSaturationSelection
@setSaturation _offsetX, _offsetY
@refreshColor 'saturation'
do => # Bind the alpha selector controls
_isGrabbingAlphaSelection = false
$body.on 'mousedown mousemove mouseup', (e) =>
_offsetTop = AlphaSelector.$el.offset().top
_offsetY = Math.max 1, (Math.min AlphaSelector.height, (e.pageY - _offsetTop))
switch e.type
when 'mousedown'
return unless e.target.className is 'ColorPicker-alphaSelector'
e.preventDefault()
_isGrabbingAlphaSelection = true
when 'mousemove'
return unless _isGrabbingAlphaSelection
e.preventDefault()
when 'mouseup'
_isGrabbingAlphaSelection = false
return unless _isGrabbingAlphaSelection
@setAlpha _offsetY
@refreshColor 'alpha'
do => # Bind the hue selector controls
_isGrabbingHueSelection = false
$body.on 'mousedown mousemove mouseup', (e) =>
_offsetTop = HueSelector.$el.offset().top
_offsetY = Math.max 1, (Math.min HueSelector.height, (e.pageY - _offsetTop))
switch e.type
when 'mousedown'
return unless e.target.className is 'ColorPicker-hueSelector'
e.preventDefault()
_isGrabbingHueSelection = true
when 'mousemove'
return unless _isGrabbingHueSelection
e.preventDefault()
when 'mouseup'
_isGrabbingHueSelection = false
return unless _isGrabbingHueSelection
@setHue _offsetY
@refreshColor 'hue'
# -------------------------------------
# Saturation
# -------------------------------------
setSaturation: (positionX, positionY) ->
@storage.saturation.x = positionX
@storage.saturation.y = positionY
_percentageTop = (positionY / SaturationSelector.height) * 100
_percentageLeft = (positionX / SaturationSelector.width) * 100
SaturationSelector.$selection
.css 'top', _percentageTop + '%'
.css 'left', _percentageLeft + '%'
refreshSaturationCanvas: ->
_color = HueSelector.getColorAtPosition @storage.hue
SaturationSelector.render _color.color
# -------------------------------------
# Alpha
# -------------------------------------
setAlpha: (positionY) ->
@storage.alpha = positionY
AlphaSelector.$selection
.css 'top', (positionY / AlphaSelector.height) * 100 + '%'
refreshAlphaCanvas: ->
_saturation = @storage.saturation
_color = SaturationSelector.getColorAtPosition _saturation.x, _saturation.y
AlphaSelector.render Convert.hexToRgb _color.color
# -------------------------------------
# Hue
# -------------------------------------
setHue: (positionY) ->
@storage.hue = positionY
HueSelector.$selection
.css 'top', (positionY / HueSelector.height) * 100 + '%'
# -------------------------------------
# Color
# -------------------------------------
# Set the current color after control interaction
setColor: (color, preferredColorType) ->
unless color then this.removeClass 'is--initial'
else _setInitialColor = true
_saturation = @storage.saturation
color ?= SaturationSelector.getColorAtPosition _saturation.x, _saturation.y
_color = _displayColor = color.color
_alphaValue = 100 - (((@storage.alpha / AlphaSelector.height) * 100) << 0)
_alphaFactor = _alphaValue / 100
# Spit the same color type as the input (selected) color
if preferredColorType
if preferredColorType is 'hsl' or preferredColorType is 'hsla'
_hsl = Convert.hsvToHsl Convert.rgbToHsv Convert.hexToRgb _color
_h = (_hsl[0]) << 0
_s = (_hsl[1] * 100) << 0
_l = (_hsl[2] * 100) << 0
else _hexRgbFragments = (Convert.hexToRgb _color).join ', '
if _alphaValue is 100 then _displayColor = switch preferredColorType
when 'rgb', 'rgba' then "rgb(#{ _hexRgbFragments })"
when 'hsl', 'hsla' then "hsl(#{ _h }, #{ _s }%, #{ _l }%)"
else _color
else _displayColor = switch preferredColorType
when 'rgb', 'rgba', 'hex' then "rgba(#{ _hexRgbFragments }, #{ _alphaFactor })"
when 'hexa' then "rgba(#{ _color }, #{ _alphaFactor })"
when 'hsl', 'hsla' then "hsla(#{ _h }, #{ _s }%, #{ _l }%, #{ _alphaFactor })"
# Translate the color to rgba if an alpha value is set
if _alphaValue isnt 100
_rgb = switch color.type
when 'hexa' then Convert.hexaToRgb _color
when 'hex' then Convert.hexToRgb _color
when 'rgb' then _color
if _rgb then _color = "rgba(#{ _rgb.join ', ' }, #{ _alphaFactor })"
@storage.pickedColor = _displayColor
# Set the color
(this.find '#ColorPicker-color')
.css 'background-color', _color
.css 'border-bottom-color', _color
(this.find '#ColorPicker-value').html _displayColor
# Save the initial color this function is given it
if _setInitialColor
(this.find '#ColorPicker-initial')
.css 'background-color', _color
.html _displayColor
# The color is a variable
if color.hasOwnProperty 'pointer'
this.removeClass 'is--searching'
.find '#ColorPicker-value'
.attr 'data-variable', color.match
refreshColor: (trigger) ->
if trigger is 'hue' then @refreshSaturationCanvas()
if trigger is 'hue' or trigger is 'saturation' then @refreshAlphaCanvas()
# Send the preferred color type as well
@setColor undefined, @storage.selectedColor.type
# User selects a new color, reflect the change
inputColor: (color) ->
_hasClass = this[0].className.match /(is\-\-color\_(\w+))\s/
this.removeClass _hasClass[1] if _hasClass
this.addClass "is--color_#{ color.type }"
_color = color.color
# Convert the color to HSV
# _hsv needs to be an array [h, s, v]
_hsv = switch color.type
when 'hex' then Convert.rgbToHsv Convert.hexToRgb _color
when 'hexa' then Convert.rgbToHsv Convert.hexaToRgb _color
when 'rgb', 'rgba' then Convert.rgbToHsv _color
when 'hsl', 'hsla' then Convert.hslToHsv [
(parseInt color.regexMatch[1], 10)
(parseInt color.regexMatch[2], 10) / 100
(parseInt color.regexMatch[3], 10) / 100]
return unless _hsv
# Set all controls in the right place to reflect the input color
# Get the hue. 360 is the H max
@setHue (HueSelector.height / 360) * _hsv[0]
# Get the saturation
_saturationX = Math.max 1, SaturationSelector.width * _hsv[1]
_saturationY = Math.max 1, SaturationSelector.height * (1 - _hsv[2])
@setSaturation _saturationX, _saturationY
@refreshSaturationCanvas()
# Get the alpha
_alpha = switch color.type
when 'rgba' then color.regexMatch[7]
when 'hexa' then color.regexMatch[4]
when 'hsla' then color.regexMatch[4]
# Set the alpha
if _alpha then @setAlpha AlphaSelector.height * (1 - parseFloat _alpha)
else if not _alpha then @setAlpha 0
@refreshAlphaCanvas()
@setColor color
# -------------------------------------
# Selection
# -------------------------------------
# Select the color in the editor
selectColor: ->
_color = @storage.selectedColor
_editor = atom.workspace.getActiveEditor()
return unless _color
# Clear selections and select the color
_editor.clearSelections()
_editor.addSelectionForBufferRange
start:
column: _color.index
row: _color.row
end:
column: _color.end
row: _color.row
replaceColor: ->
_color = @storage.selectedColor
_newColor = @storage.pickedColor
_editor = atom.workspace.getActiveEditor()
return unless _color
@selectColor()
# Replace the text
_editor.replaceSelectedText null, => return _newColor
# Clear selections and select the color
_editor.clearSelections()
_editor.addSelectionForBufferRange
start:
column: _color.index
row: _color.row
end:
column: _color.index + _newColor.length
row: _color.row

@ -0,0 +1,157 @@
# ----------------------------------------------------------------------------
# ColorPicker
# ----------------------------------------------------------------------------
Convert = require './ColorPicker-convert'
ConditionalContextMenu = require './conditional-contextmenu'
VariableInspector = require './variable-inspector'
_regexes = require './ColorPicker-regexes'
# -------------------------------------
# Public functionality
# -------------------------------------
module.exports =
view: null
match: null
activate: ->
atom.workspaceView.command "color-picker:open", => @open true
ConditionalContextMenu.item {
label: 'Color picker'
command: 'color-picker:open',
}, => return true if @match = @getMatchAtCursor()
ColorPickerView = require './ColorPicker-view'
@view = new ColorPickerView
deactivate: -> @view.destroy()
# Get a match at the current cursor position
getMatchAtCursor: ->
return unless _editor = atom.workspace.getActiveEditor()
_line = _editor.getCursor().getCurrentBufferLine()
_cursorBuffer = _editor.getCursorBufferPosition()
_cursorRow = _cursorBuffer.row
_cursorColumn = _cursorBuffer.column
return @matchAtPosition _cursorColumn, (@matchesOnLine _line, _cursorRow)
# Match the current line against the regexes
# @String line
# @Number cursorRow
matchesOnLine: (line, cursorRow) ->
return unless line and typeof cursorRow is 'number'
_filteredMatches = []; for { type, regex } in _regexes
continue unless _matches = line.match regex
for match in _matches
# Skip if the match has been used already
continue if (_index = line.indexOf match) is -1
_filteredMatches.push
match: match
regexMatch: match.match RegExp regex.source, 'i'
type: type
index: _index
end: _index + match.length
row: cursorRow
# Make sure the indices are correct by removing
# the instances from the string after use
line = line.replace match, (Array match.length + 1).join ' '
return unless _filteredMatches.length > 0
return _filteredMatches
# Get a single match on a position based on a match array
# as seen in matchesOnLine
# @Number column
# @Array matches
matchAtPosition: (column, matches) ->
return unless column and matches
_match = do -> for match in matches
if match.index <= column and match.end >= column
return match
return _match
open: (getMatch = false) ->
if getMatch then @match = @getMatchAtCursor()
if not @match
randomRGBFragment = -> (Math.random() * 255) << 0
_line = '#' + Convert.rgbToHex [randomRGBFragment(), randomRGBFragment(), randomRGBFragment()]
_cursorBuffer = atom.workspace.getActiveEditor().getCursorBufferPosition()
_cursorRow = _cursorBuffer.row
_cursorColumn = _cursorBuffer.column
_match = (@matchesOnLine _line, _cursorRow)[0]
_match.index = _cursorColumn
_match.end = _cursorColumn
@match = _match
return unless @match
@view.reset()
@setMatchColor()
@view.open()
# Set the color of a match to its object, and then send it
# to the color picker view
# @Object match
# @Function callback
setMatchColor: ->
return unless @match
@view.storage.selectedColor = null
if @match.hasOwnProperty 'color'
@view.storage.selectedColor = @match
@view.inputColor @match
return
_callback = => @setMatchColor()
return switch @match.type
when 'variable:sass' then @setVariableDefinitionColor @match, _callback
when 'variable:less' then @setVariableDefinitionColor @match, _callback
else do => @match.color = @match.match; _callback @match
# Set the variable definition by sending it through a
# provided callback when found
# @Object match
# @Function callback
setVariableDefinitionColor: (match, callback) ->
return unless match and callback
_matchRegex = regex for { type, regex } in _regexes when type is match.type
_variableName = (match.match.match RegExp _matchRegex.source, 'i')[2] # hahaha
(@findVariableDefinition _variableName, match.type).then ({ color, pointer }) ->
match.color = color.match
match.type = color.type
match.pointer = pointer
callback match
# Find variable definition by searching recursively until a
# non-variable (a color) is found
# @String name
# @String type
findVariableDefinition: (name, type, pointer) ->
return (VariableInspector.findDefinition name, type).then (definition) =>
pointer ?= definition.pointer # remember the initial pointer
_matches = @matchesOnLine definition.definition, 1
return @view.error() unless _matches and _color = _matches[0]
# Continue digging for the truth and real definition
if (_color.type.split ':')[0] is 'variable'
return @findVariableDefinition _color.regexMatch[2], _color.type, pointer
return { color: _color, pointer: pointer }

@ -0,0 +1,22 @@
# ----------------------------------------------------------------------------
# Conditional Context Menu items
# ----------------------------------------------------------------------------
module.exports =
# Add a context menu item and show it or not based on a condition
# @Object definition { label: '', command: '' }
# @Function condition
item: (definition, condition) -> atom.workspaceView.contextmenu =>
_label = definition.label
_command = definition.command
_definitions = atom.contextMenu.definitions['.overlayer']
_hasItem = true for item in _definitions when item.label is _label and item.command is _command
if condition() then unless _hasItem
_definitions.unshift
label: _label
command: _command
else for item, i in _definitions when item
if item.label is _label
_definitions.splice i, 1

@ -0,0 +1,86 @@
# ----------------------------------------------------------------------------
# Variable inspector
# ----------------------------------------------------------------------------
_definitions = {}
# -------------------------------------
# Variable patterns
# -------------------------------------
_variablePatterns = {
'variable:sass': '\\${{ VARIABLE }}[\\s]*\\:[\\s]*(.+)[\\;|\\n]?'
'variable:less': '\\@{{ VARIABLE }}[\\s]*\\:[\\s]*(.+)[\\;|\\n]?'
}
# -------------------------------------
# File path patterns
# -------------------------------------
_globPatterns = {
'variable:sass': ['**/*.scss', '**/*.sass']
'variable:less': ['**/*.less']
}
# -------------------------------------
# Public functionality
# -------------------------------------
module.exports =
# Find a variable definition in the project
# @String name
# @String type
findDefinition: (name, type) ->
return unless _regexString = _variablePatterns[type]
_regex = RegExp (_regexString.replace '{{ VARIABLE }}', name)
_results = []
# We already know where the definition is
if _definition = _definitions[name]
_pointer = _definition.pointer
return (atom.project.bufferForPath _pointer.filePath).then (buffer) =>
_text = buffer.getTextInRange _pointer.range
_match = _text.match _regex
unless _match
_definitions[name] = null
return @findDefinition name, type
_definition.definition = _match[1]
return _definition
_options = unless _globPatterns[type] then null else {
paths: _globPatterns[type]
}
# We don't know where the definition is, look it up
atom.project.scan _regex, _options, (result) ->
_results.push result
.then =>
# Figure out what file is holding the definition
# Assume it's the one closest to the current path
_targetPath = atom.workspaceView.getActivePaneItem().getPath()
_targetFragments = _targetPath.split '/'
_bestMatch = null
_bestMatchHits = 0
for result in _results
_thisMatchHits = 0
_pathFragments = result.filePath.split '/'
_thisMatchHits++ for pathFragment, i in _pathFragments when pathFragment is _targetFragments[i]
if _thisMatchHits > _bestMatchHits
_bestMatch = result
_bestMatchHits = _thisMatchHits
return this unless _bestMatch and _match = _bestMatch.matches[0]
_definitions[name] = {
name: name
type: type
pointer:
filePath: _bestMatch.filePath
range: _match.range
}
return @findDefinition name, type

@ -0,0 +1,4 @@
# See https://atom.io/docs/latest/creating-a-package#menus for more details
'context-menu':
'.overlayer':
'Color picker': 'color-picker:open'

@ -0,0 +1,27 @@
{
"name": "color-picker",
"main": "./lib/ColorPicker",
"version": "1.1.0",
"private": true,
"description": "A Color Picker for the Atom Editor. Right click a color and select color picker to open it.",
"repository": {
"type": "git",
"url": "https://github.com/thomaslindstrom/color-picker"
},
"license": "MIT",
"engines": {
"atom": ">0.50.0"
},
"readme": "# A Color Picker for Atom\n\nA color picker for Atom. Either right click a color and select `Color picker`, or hit `CMD-SHIFT-C`/`CTRL-ALT-C` anywhere. Currently reads HEX, HEXA, RGB, RGBA, HSL and HSLA.\n\nInspects Sass/LESS variables! [Take a look here.](http://t.hom.as/colorpicker4.mov)\n\n**NEW:** You can now open the color picker whenever, without input, using `CMD-SHIFT-C`/`CTRL-ALT-C`!\n\n## Preview\n\n![Color Picker in action](http://f.cl.ly/items/3g3T401o0o0F2m2O1z1K/output.gif)\n\n## To do\n\n- Stylus variable lookup\n- Context menu convertions\n- Preview color manipulation functions (lighten, darken)\n- Edit the color value\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/thomaslindstrom/color-picker/issues"
},
"homepage": "https://github.com/thomaslindstrom/color-picker",
"_id": "color-picker@1.1.0",
"dist": {
"shasum": "10f79bca9751160c5f2a2c97bbbfdff3fe68f26c"
},
"_resolved": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114614-4292-pnjmsa\\package.tgz",
"_from": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114614-4292-pnjmsa\\package.tgz"
}

@ -0,0 +1,59 @@
// ---------------------------------------------------------------------------
// Alpha selector
// ---------------------------------------------------------------------------
@import (reference) "color-picker.less";
.ColorPicker-alphaSelectorWrapper {
position: absolute;
bottom: @controls-margin; right: 20px + (@controls-margin * 2);
pointer-events: none;
&:before {
content: '';
background: @image-transparency;
background-size: 10px 10px;
width: 100%; height: 100%;
position: absolute;
top: 0; right: 0; left: 0;
z-index: -1;
opacity: .1; }
&:after {
content: '';
border: 2px solid @color-ui;
border-radius: 3px;
box-shadow: inset 0 0 1px rgba(0, 0, 0, .5);
position: absolute;
top: -2px; right: -2px; bottom: -2px; left: -2px;
z-index: 10; }
}
// -------------------------------------
// Current selection
// -------------------------------------
.ColorPicker-alphaSelection {
width: 18px; height: 7px;
margin-top: -4px;
border: 2px solid #fff;
border-radius: 1px;
box-shadow:
0 0 1px rgba(0, 0, 0, .3),
inset 0 0 1px rgba(0, 0, 0, .6);
position: absolute;
top: 0; right: 1px; left: 1px;
z-index: 20;
pointer-events: none; }
// -------------------------------------
// Selector bar
// -------------------------------------
.ColorPicker-alphaSelector {
width: 20px; height: @controls-height;
display: block;
cursor: -webkit-grab;
cursor: grab;
pointer-events: all;
&:active {
cursor: -webkit-grabbing;
cursor: grabbing; }
}

@ -0,0 +1,138 @@
// ---------------------------------------------------------------------------
// Color output
// ---------------------------------------------------------------------------
@import (reference) "color-picker.less";
.ColorPicker-color {
width: 100%; height: @picker-height--pointer;
cursor: pointer;
text-align: center;
border-radius: 2px 2px 0 0;
position: absolute;
top: 0;
&:before {
content: '';
background: @image-transparency;
background-size: 10px 10px;
width: 100%; height: 100%;
position: absolute;
top: 0; right: 0; left: 0;
z-index: -1;
opacity: .1; }
&:after {
content: '';
width: 0; height: 0;
margin: auto;
border: 8px solid transparent;
border-bottom-color: inherit;
position: absolute;
top: -16px; left: 0; right: 0; }
.no--arrow &:after { display: none; }
.is--pointer & { border-radius: 2px; }
.is--searching &:after { display: none; }
}
.ColorPicker-value,
.ColorPicker-initial {
font-family: 'Source Code Pro', @font-family;
color: #fff;
text-align: center;
text-shadow:
0 2px 30px rgba(0, 0, 0, .5),
0 0 2px rgba(0, 0, 0, .3),
0 1px 1px rgba(0, 0, 0, .1),
0 1px rgba(0, 0, 0, .1),
0 -1px 4px rgba(0, 0, 0, .1),
0 0 1px rgba(0, 0, 0, .3); }
// -------------------------------------
// Current color
// -------------------------------------
.ColorPicker-value {
font-size: 17px;
font-weight: 400;
position: absolute;
top: 50%; right: 0; left: 0;
pointer-events: none;
-webkit-transition: -webkit-transform .3s;
-webkit-transform: translate(0, -105%);
-webkit-backface-visibility: hidden;
-webkit-transform-style: preserve-3d;
.is--color_hsla & { font-size: 15px; }
.ColorPicker-color:hover & { -webkit-transform: translate(0, -140%); }
.is--initial & { -webkit-transform: translate(0, -50%); }
.is--initial .ColorPicker-color:hover & { -webkit-transform: translate(0, -90%); }
.is--pointer & { -webkit-transform: translate(0, -90%); }
.is--pointer .ColorPicker-color:hover & { -webkit-transform: translate(0, -95%) scale(1.1); }
.is--error &,
.is--error .ColorPicker-color:hover & { -webkit-transform: translate(0, -50%); }
.is--pointer &:after {
content: attr(data-variable);
font-size: 11px;
color: #fff;
text-overflow: ellipsis;
text-shadow: 0 0 1px #000;
white-space: nowrap;
margin: auto;
overflow: hidden;
position: absolute;
top: 30px; right: 5px; left: 5px; }
.is--searching & { display: none; }
.is--error &:after {
content: 'No color found :(';
font-size: 11px;
color: #000;
text-shadow: none;
margin: auto;
overflow: hidden;
top: -5px; right: 5px; left: 5px; }
}
// -------------------------------------
// Initial color
// -------------------------------------
.ColorPicker-initialWrapper {
background: #fff;
width: 100%;
cursor: pointer;
position: absolute;
top: @picker-height--pointer - 30;
-webkit-backface-visibility: hidden;
-webkit-transition: -webkit-transform .3s;
-webkit-transform: translate3d(0, 0, 0);
&:hover { -webkit-transform: translate(0, -20%); }
.is--initial & {
pointer-events: none;
-webkit-transform: translate(0, 100%); }
.is--pointer & { display: none; }
&:before {
content: '';
background: @image-transparency;
background-size: 10px 10px;
width: 100%; height: 100%;
position: absolute;
top: 0; right: 0; left: 0;
z-index: -1;
opacity: .1; }
}
.ColorPicker-initial {
font-weight: 300;
padding: 6px 0 20px;
pointer-events: none; }

@ -0,0 +1,47 @@
// ---------------------------------------------------------------------------
// Hue selector
// ---------------------------------------------------------------------------
@import (reference) "color-picker.less";
.ColorPicker-hueSelectorWrapper {
position: absolute;
bottom: @controls-margin; right: @controls-margin;
pointer-events: none;
&:after {
content: '';
border: 2px solid @color-ui;
border-radius: 3px;
box-shadow: inset 0 0 1px rgba(0, 0, 0, .5);
position: absolute;
top: -2px; right: -2px; bottom: -2px; left: -2px;
z-index: 10; }
}
// -------------------------------------
// Current selection
// -------------------------------------
.ColorPicker-hueSelection {
width: 18px; height: 7px;
margin-top: -4px;
border: 2px solid #fff;
border-radius: 1px;
box-shadow:
0 0 1px rgba(0, 0, 0, .3),
inset 0 0 1px rgba(0, 0, 0, .6);
position: absolute;
top: 1px; right: 1px; left: 1px;
z-index: 20;
pointer-events: none; }
// -------------------------------------
// Selector bar
// -------------------------------------
.ColorPicker-hueSelector {
width: 20px; height: @controls-height;
display: block;
cursor: -webkit-grab;
pointer-events: all;
&:active { cursor: -webkit-grabbing; }
}

@ -0,0 +1,46 @@
// ---------------------------------------------------------------------------
// Loader
// ---------------------------------------------------------------------------
@import (reference) "color-picker.less";
.ColorPicker-loader {
background: rgba(0, 0, 0, .4);
width: 100%; height: @picker-height--pointer;
font-size: 0;
text-align: center;
pointer-events: none;
position: absolute;
top: 0;
z-index: 40;
opacity: 0;
-webkit-transition: opacity .3s;
.is--searching & { opacity: 1; }
.is--error & { opacity: 0; }
}
.is--searching .ColorPicker-loaderDot {
background: #fff;
width: 14px; height: 14px;
border-radius: 100%;
margin: -7px 4px 0;
position: relative;
top: 50%;
display: inline-block;
-webkit-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
-webkit-animation: inflate alternate infinite .7s ease-in-out;
-webkit-animation-fill-mode: both;
-webkit-animation-play-state: running;
&:nth-child(2) { -webkit-animation-delay: .1s; }
&:nth-child(3) { -webkit-animation-delay: .2s; }
}
@-webkit-keyframes inflate {
0%, 40% { -webkit-transform: scale(0); }
100% { -webkit-transform: scale(1); }
}

@ -0,0 +1,44 @@
// ---------------------------------------------------------------------------
// Saturation selector
// ---------------------------------------------------------------------------
@import (reference) "color-picker.less";
.ColorPicker-saturationSelectorWrapper {
position: absolute;
bottom: @controls-margin; left: @controls-margin;
pointer-events: none;
&:after {
content: '';
border: 2px solid @color-ui;
border-radius: 3px;
box-shadow: inset 0 0 1px rgba(0, 0, 0, .5);
position: absolute;
top: -2px; right: -2px; bottom: -2px; left: -2px;
z-index: 10; }
}
// -------------------------------------
// Current selection
// -------------------------------------
.ColorPicker-saturationSelection {
width: 10px; height: 10px;
margin: -5px 0 0 -5px;
border: 2px solid #fff;
border-radius: 100%;
box-shadow:
0 0 1px rgba(0, 0, 0, .3),
inset 0 0 1px rgba(0, 0, 0, .8);
position: absolute;
top: 100%; left: 0;
z-index: 20;
pointer-events: none; }
// -------------------------------------
// Selector area
// -------------------------------------
.ColorPicker-saturationSelector {
width: @controls-height; height: @controls-height;
cursor: crosshair;
display: block;
pointer-events: all; }

@ -0,0 +1,69 @@
// The ui-variables file is provided by base themes provided by Atom.
//
// See https://github.com/atom/atom-dark-ui/blob/master/stylesheets/ui-variables.less
// for a full listing of what's available.
@import "ui-variables";
// ---------------------------------------------------------------------------
// Color picker: style
// ---------------------------------------------------------------------------
@color-ui: #ebebeb;
@picker-width: 260px;
@picker-height: 300px;
@picker-height--pointer: 100px;
@controls-height: 180px;
@controls-margin: 10px;
@image-transparency: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAJElEQVQIW2PcvXv3fwYg6OzsBFEMjBgCLi4uYBXl5eUQFegCAIYVD/syLxKnAAAAAElFTkSuQmCC);
.ColorPicker {
background: #fff;
width: @picker-width; height: @picker-height;
border-radius: 3px 3px 2px 2px;
box-shadow: 0 10px 30px 10px rgba(0, 0, 0, .3);
position: absolute;
top: 50%; bottom: 0;
z-index: 40;
visibility: hidden;
opacity: 0;
pointer-events: none;
-webkit-transform-origin: 50% 0;
-webkit-transition:
-webkit-transform .15s,
opacity .15s,
visibility 0 .15s;
-webkit-transform: scale(.6);
-webkit-backface-visibility: hidden;
-webkit-transform-style: preserve-3d;
&.is--visible {
visibility: visible;
opacity: 1;
pointer-events: all;
-webkit-transition:
-webkit-transform .2s,
opacity .2s;
-webkit-transform: scale(1); }
&.is--pointer { height: @picker-height--pointer; }
}
// -------------------------------------
// Picker
// -------------------------------------
.ColorPicker-picker {
background: @color-ui;
width: 100%; height: @controls-height + (@controls-margin * 2);
box-shadow: 0 -1px rgba(0, 0, 0, .2);
position: absolute;
bottom: 0;
z-index: 1;
border-radius: 0 0 3px 3px;
.is--pointer & { display: none; }
}

@ -0,0 +1,8 @@
language: objective-c
notifications:
email:
on_success: never
on_failure: change
script: 'curl -s https://raw.githubusercontent.com/atom/ci/master/build-package.sh | sh'

@ -0,0 +1 @@
See the [Atom contributing guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md)

@ -0,0 +1,20 @@
Copyright (c) 2014 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,9 @@
# Editor Stats package [![Build Status](https://travis-ci.org/atom/editor-stats.svg?branch=master)](https://travis-ci.org/atom/editor-stats)
View a graph of your mouse and keyboard activity for the last 6 hours.
The blue bar indicates the time of greatest activity.
Use `cmd-alt-s` to open and close the graph.
![](https://f.cloud.github.com/assets/671378/2262223/843b1172-9e57-11e3-9c60-8d28d542f39c.png)

@ -0,0 +1,5 @@
'.platform-darwin':
'cmd-alt-s': 'editor-stats:toggle'
'.platform-win32':
'alt-ctrl-s': 'editor-stats:toggle'

@ -0,0 +1,103 @@
_ = require 'underscore-plus'
{$, ScrollView} = require 'atom'
d3 = require 'd3-browserify'
module.exports =
class EditorStatsView extends ScrollView
@activate: ->
new EditorStatsView
@content: ->
@div class: 'editor-stats-wrapper', tabindex: -1, =>
@div class: 'editor-stats', outlet: 'editorStats'
pt: 15
pl: 10
pb: 3
pr: 25
initialize: ->
super
resizer = =>
return unless @isOnDom()
@draw()
@update()
@subscribe $(window), 'resize', _.debounce(resizer, 300)
draw: ->
@editorStats.empty()
@x ?= d3.scale.ordinal().domain d3.range(@stats.hours * 60)
@y ?= d3.scale.linear()
w = atom.workspaceView.vertical.width()
h = @height()
data = d3.entries @stats.eventLog
max = d3.max data, (d) -> d.value
@x.rangeBands [0, w - @pl - @pr], 0.2
@y.domain([0, max]).range [h - @pt - @pb, 0]
@xaxis ?= d3.svg.axis().scale(@x).orient('top')
.tickSize(-h + @pt + @pb)
.tickFormat (d) =>
d = new Date(@stats.startDate.getTime() + (d * 6e4))
mins = d.getMinutes()
mins = "0#{mins}" if mins <= 9
"#{d.getHours()}:#{mins}"
vis = d3.select(@editorStats.get(0)).append('svg')
.attr('width', w)
.attr('height', h)
.append('g')
.attr('transform', "translate(#{@pl},#{@pt})")
vis.append('g')
.attr('class', 'x axis')
.call(@xaxis)
.selectAll('g')
.classed('minor', (d, i) -> i % 5 == 0 && i % 15 != 0)
.style 'display', (d, i) ->
if i % 15 == 0 || i % 5 == 0 || i == data.length - 1
'block'
else
'none'
@bars = vis.selectAll('rect.bar')
.data(data)
.enter().append('rect')
.attr('x', (d, i) => @x i)
.attr('height', (d, i) => h - @y(d.value) - @pt - @pb)
.attr('y', (d) => @y(d.value))
.attr('width', @x.rangeBand())
.attr('class', 'bar')
clearInterval(@updateInterval)
updater = => @update() if @isOnDom()
setTimeout(updater, 100)
@updateInterval = setInterval(updater, 5000)
update: ->
newData = d3.entries @stats.eventLog
max = d3.max newData, (d) -> d.value
@y.domain [0, max]
h = @height()
@bars.data(newData).transition()
.attr('height', (d, i) => h - @y(d.value) - @pt - @pb)
.attr('y', (d, i) => @y(d.value))
@bars.classed('max', (d, i) -> d.value == max)
toggle: (@stats) ->
if @hasParent()
@detach()
else
@attach()
attach: ->
atom.workspaceView.prependToBottom(this)
@draw()
detach: ->
super
clearInterval(@updateInterval)
atom.workspaceView.focus()

@ -0,0 +1,17 @@
StatsTracker = require './stats-tracker'
module.exports =
activate: ->
@stats = new StatsTracker()
atom.workspaceView.command 'editor-stats:toggle', =>
@createView().toggle(@stats)
deactivate: ->
@editorStatsView = null
@stats = null
createView: ->
unless @editorStatsView
EditorStatsView = require './editor-stats-view'
@editorStatsView = new EditorStatsView()
@editorStatsView

@ -0,0 +1,32 @@
module.exports =
class StatsTracker
startDate: new Date
hours: 6
eventLog: {}
constructor: ->
date = new Date(@startDate)
future = new Date(date.getTime() + (36e5 * @hours))
@eventLog[@time(date)] = 0
while date < future
@eventLog[@time(date)] = 0
atom.workspaceView.on 'keydown', => @track()
atom.workspaceView.on 'mouseup', => @track()
clear: ->
@eventLog = {}
track: ->
date = new Date
times = @time date
@eventLog[times] ?= 0
@eventLog[times] += 1
@eventLog.shift() if @eventLog.length > (@hours * 60)
time: (date) ->
date.setTime(date.getTime() + 6e4)
hour = date.getHours()
minute = date.getMinutes()
"#{hour}:#{minute}"

@ -0,0 +1,9 @@
'menu': [
'label': 'Packages'
'submenu': [
'label': 'Editor Stats'
'submenu': [
{ 'label': 'Toggle', 'command': 'editor-stats:toggle' }
]
]
]

@ -0,0 +1,3 @@
# d3-browserify
D3 distribution that used for browserify-like environment.

File diff suppressed because it is too large Load Diff

@ -0,0 +1,47 @@
{
"name": "d3-browserify",
"version": "3.3.13",
"description": "A small, free JavaScript library for manipulating documents based on data.",
"keywords": [
"dom",
"w3c",
"visualization",
"svg",
"animation",
"canvas"
],
"homepage": "http://d3js.org",
"author": {
"name": "Mike Bostock",
"url": "http://bost.ocks.org/mike"
},
"contributors": [
{
"name": "Jason Davies",
"url": "http://jasondavies.com"
}
],
"repository": {
"type": "git",
"url": "https://github.com/zcbenz/d3-browserify.git"
},
"main": "d3.js",
"browserify": "d3.js",
"licenses": [
{
"type": "BSD",
"url": "https://github.com/mbostock/d3/blob/master/LICENSE"
}
],
"readme": "# d3-browserify\n\nD3 distribution that used for browserify-like environment.\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/zcbenz/d3-browserify/issues"
},
"_id": "d3-browserify@3.3.13",
"dist": {
"shasum": "dc8384a2f78bf7c88c39bedd5dbfde95fecc1f2a"
},
"_from": "d3-browserify@3.3.13",
"_resolved": "https://registry.npmjs.org/d3-browserify/-/d3-browserify-3.3.13.tgz"
}

@ -0,0 +1,20 @@
Copyright (c) 2013 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,14 @@
# underscore-plus [![Build Status](https://travis-ci.org/atom/underscore-plus.svg?branch=master)](https://travis-ci.org/atom/underscore-plus)
Takes the great [underscore](http://underscorejs.org/) library and adds a few
more things.
## Using
```sh
npm install underscore-plus
```
```coffeescript
_ = require 'underscore-plus' # Has all underscore methods and more
```

@ -0,0 +1,498 @@
(function() {
var isEqual, macModifierKeyMap, nonMacModifierKeyMap, plus, shiftKeyMap, _,
__slice = [].slice;
_ = require('underscore');
macModifierKeyMap = {
cmd: '\u2318',
ctrl: '\u2303',
alt: '\u2325',
option: '\u2325',
shift: '\u21e7',
enter: '\u23ce',
left: '\u2190',
right: '\u2192',
up: '\u2191',
down: '\u2193'
};
nonMacModifierKeyMap = {
cmd: 'Cmd',
ctrl: 'Ctrl',
alt: 'Alt',
option: 'Alt',
shift: 'Shift',
enter: 'Enter',
left: 'Left',
right: 'Right',
up: 'Up',
down: 'Down'
};
shiftKeyMap = {
'~': '`',
'_': '-',
'+': '=',
'|': '\\',
'{': '[',
'}': ']',
':': ';',
'"': '\'',
'<': ',',
'>': '.',
'?': '/'
};
plus = {
adviseBefore: function(object, methodName, advice) {
var original;
original = object[methodName];
return object[methodName] = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
if (advice.apply(this, args) !== false) {
return original.apply(this, args);
}
};
},
camelize: function(string) {
if (string) {
return string.replace(/[_-]+(\w)/g, function(m) {
return m[1].toUpperCase();
});
} else {
return '';
}
},
capitalize: function(word) {
if (!word) {
return '';
}
if (word.toLowerCase() === 'github') {
return 'GitHub';
} else {
return word[0].toUpperCase() + word.slice(1);
}
},
compactObject: function(object) {
var key, newObject, value;
newObject = {};
for (key in object) {
value = object[key];
if (value != null) {
newObject[key] = value;
}
}
return newObject;
},
dasherize: function(string) {
if (!string) {
return '';
}
string = string[0].toLowerCase() + string.slice(1);
return string.replace(/([A-Z])|(_)/g, function(m, letter) {
if (letter) {
return "-" + letter.toLowerCase();
} else {
return "-";
}
});
},
deepClone: function(object) {
if (_.isArray(object)) {
return object.map(function(value) {
return plus.deepClone(value);
});
} else if (_.isObject(object)) {
return plus.mapObject(object, (function(_this) {
return function(key, value) {
return [key, plus.deepClone(value)];
};
})(this));
} else {
return object;
}
},
deepExtend: function() {
var key, object, objects, result, value, _i, _len;
objects = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
result = {};
for (_i = 0, _len = objects.length; _i < _len; _i++) {
object = objects[_i];
for (key in object) {
value = object[key];
if (_.isObject(value) && !_.isArray(value)) {
result[key] = plus.deepExtend(result[key], value);
} else {
if (result[key] == null) {
result[key] = value;
}
}
}
}
return result;
},
deepContains: function(array, target) {
var object, _i, _len;
if (array == null) {
return false;
}
for (_i = 0, _len = array.length; _i < _len; _i++) {
object = array[_i];
if (_.isEqual(object, target)) {
return true;
}
}
return false;
},
endsWith: function(string, suffix) {
if (suffix == null) {
suffix = '';
}
if (string) {
return string.indexOf(suffix, string.length - suffix.length) !== -1;
} else {
return false;
}
},
escapeAttribute: function(string) {
if (string) {
return string.replace(/"/g, '&quot;').replace(/\n/g, '').replace(/\\/g, '-');
} else {
return '';
}
},
escapeRegExp: function(string) {
if (string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
} else {
return '';
}
},
humanizeEventName: function(eventName, eventDoc) {
var event, namespace, namespaceDoc, _ref;
_ref = eventName.split(':'), namespace = _ref[0], event = _ref[1];
if (event == null) {
return plus.undasherize(namespace);
}
namespaceDoc = plus.undasherize(namespace);
if (eventDoc == null) {
eventDoc = plus.undasherize(event);
}
return "" + namespaceDoc + ": " + eventDoc;
},
humanizeKey: function(key, platform) {
var modifierKeyMap;
if (platform == null) {
platform = process.platform;
}
if (!key) {
return key;
}
modifierKeyMap = platform === 'darwin' ? macModifierKeyMap : nonMacModifierKeyMap;
if (modifierKeyMap[key]) {
return modifierKeyMap[key];
} else if (key.length === 1 && (shiftKeyMap[key] != null)) {
return [modifierKeyMap.shift, shiftKeyMap[key]];
} else if (key.length === 1 && key === key.toUpperCase() && key.toUpperCase() !== key.toLowerCase()) {
return [modifierKeyMap.shift, key.toUpperCase()];
} else if (key.length === 1 || /f[0-9]{1,2}/.test(key)) {
return key.toUpperCase();
} else {
if (platform === 'darwin') {
return key;
} else {
return plus.capitalize(key);
}
}
},
humanizeKeystroke: function(keystroke, platform) {
var humanizedKeystrokes, index, key, keys, keystrokes, splitKeystroke, _i, _j, _len, _len1;
if (platform == null) {
platform = process.platform;
}
if (!keystroke) {
return keystroke;
}
keystrokes = keystroke.split(' ');
humanizedKeystrokes = [];
for (_i = 0, _len = keystrokes.length; _i < _len; _i++) {
keystroke = keystrokes[_i];
keys = [];
splitKeystroke = keystroke.split('-');
for (index = _j = 0, _len1 = splitKeystroke.length; _j < _len1; index = ++_j) {
key = splitKeystroke[index];
if (key === '' && splitKeystroke[index - 1] === '') {
key = '-';
}
if (key) {
keys.push(plus.humanizeKey(key, platform));
}
}
keys = _.uniq(_.flatten(keys));
if (platform === 'darwin') {
keys = keys.join('');
} else {
keys = keys.join('+');
}
humanizedKeystrokes.push(keys);
}
return humanizedKeystrokes.join(' ');
},
isSubset: function(potentialSubset, potentialSuperset) {
return _.every(potentialSubset, function(element) {
return _.include(potentialSuperset, element);
});
},
losslessInvert: function(hash) {
var inverted, key, value;
inverted = {};
for (key in hash) {
value = hash[key];
if (inverted[value] == null) {
inverted[value] = [];
}
inverted[value].push(key);
}
return inverted;
},
mapObject: function(object, iterator) {
var key, newObject, value, _ref;
newObject = {};
for (key in object) {
value = object[key];
_ref = iterator(key, value), key = _ref[0], value = _ref[1];
newObject[key] = value;
}
return newObject;
},
multiplyString: function(string, n) {
var finalString, i;
finalString = "";
i = 0;
while (i < n) {
finalString += string;
i++;
}
return finalString;
},
pluralize: function(count, singular, plural) {
if (count == null) {
count = 0;
}
if (plural == null) {
plural = singular + 's';
}
if (count === 1) {
return "" + count + " " + singular;
} else {
return "" + count + " " + plural;
}
},
remove: function(array, element) {
var index;
index = array.indexOf(element);
if (index >= 0) {
array.splice(index, 1);
}
return array;
},
setValueForKeyPath: function(object, keyPath, value) {
var key, keys;
keys = keyPath.split('.');
while (keys.length > 1) {
key = keys.shift();
if (object[key] == null) {
object[key] = {};
}
object = object[key];
}
if (value != null) {
return object[keys.shift()] = value;
} else {
return delete object[keys.shift()];
}
},
hasKeyPath: function(object, keyPath) {
var key, keys, _i, _len;
keys = keyPath.split('.');
for (_i = 0, _len = keys.length; _i < _len; _i++) {
key = keys[_i];
if (!object.hasOwnProperty(key)) {
return false;
}
object = object[key];
}
return true;
},
spliceWithArray: function(originalArray, start, length, insertedArray, chunkSize) {
var chunkStart, _i, _ref, _results;
if (chunkSize == null) {
chunkSize = 100000;
}
if (insertedArray.length < chunkSize) {
return originalArray.splice.apply(originalArray, [start, length].concat(__slice.call(insertedArray)));
} else {
originalArray.splice(start, length);
_results = [];
for (chunkStart = _i = 0, _ref = insertedArray.length; chunkSize > 0 ? _i <= _ref : _i >= _ref; chunkStart = _i += chunkSize) {
_results.push(originalArray.splice.apply(originalArray, [start + chunkStart, 0].concat(__slice.call(insertedArray.slice(chunkStart, chunkStart + chunkSize)))));
}
return _results;
}
},
sum: function(array) {
var elt, sum, _i, _len;
sum = 0;
for (_i = 0, _len = array.length; _i < _len; _i++) {
elt = array[_i];
sum += elt;
}
return sum;
},
uncamelcase: function(string) {
var result;
if (!string) {
return '';
}
result = string.replace(/([A-Z])|_+/g, function(match, letter) {
if (letter == null) {
letter = '';
}
return " " + letter;
});
return plus.capitalize(result.trim());
},
undasherize: function(string) {
if (string) {
return string.split('-').map(plus.capitalize).join(' ');
} else {
return '';
}
},
underscore: function(string) {
if (!string) {
return '';
}
string = string[0].toLowerCase() + string.slice(1);
return string.replace(/([A-Z])|-+/g, function(match, letter) {
if (letter == null) {
letter = '';
}
return "_" + (letter.toLowerCase());
});
},
valueForKeyPath: function(object, keyPath) {
var key, keys, _i, _len;
keys = keyPath.split('.');
for (_i = 0, _len = keys.length; _i < _len; _i++) {
key = keys[_i];
object = object[key];
if (object == null) {
return;
}
}
return object;
},
isEqual: function(a, b, aStack, bStack) {
if (_.isArray(aStack) && _.isArray(bStack)) {
return isEqual(a, b, aStack, bStack);
} else {
return isEqual(a, b);
}
},
isEqualForProperties: function() {
var a, b, properties, property, _i, _len;
a = arguments[0], b = arguments[1], properties = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
for (_i = 0, _len = properties.length; _i < _len; _i++) {
property = properties[_i];
if (!_.isEqual(a[property], b[property])) {
return false;
}
}
return true;
}
};
isEqual = function(a, b, aStack, bStack) {
var aCtor, aCtorValid, aElement, aKeyCount, aValue, bCtor, bCtorValid, bKeyCount, bValue, equal, i, key, stackIndex, _i, _len;
if (aStack == null) {
aStack = [];
}
if (bStack == null) {
bStack = [];
}
if (a === b) {
return _.isEqual(a, b);
}
if (_.isFunction(a) || _.isFunction(b)) {
return _.isEqual(a, b);
}
stackIndex = aStack.length;
while (stackIndex--) {
if (aStack[stackIndex] === a) {
return bStack[stackIndex] === b;
}
}
aStack.push(a);
bStack.push(b);
equal = false;
if (_.isFunction(a != null ? a.isEqual : void 0)) {
equal = a.isEqual(b, aStack, bStack);
} else if (_.isFunction(b != null ? b.isEqual : void 0)) {
equal = b.isEqual(a, bStack, aStack);
} else if (_.isArray(a) && _.isArray(b) && a.length === b.length) {
equal = true;
for (i = _i = 0, _len = a.length; _i < _len; i = ++_i) {
aElement = a[i];
if (!isEqual(aElement, b[i], aStack, bStack)) {
equal = false;
break;
}
}
} else if (_.isRegExp(a) && _.isRegExp(b)) {
equal = _.isEqual(a, b);
} else if (_.isObject(a) && _.isObject(b)) {
aCtor = a.constructor;
bCtor = b.constructor;
aCtorValid = _.isFunction(aCtor) && aCtor instanceof aCtor;
bCtorValid = _.isFunction(bCtor) && bCtor instanceof bCtor;
if (aCtor !== bCtor && !(aCtorValid && bCtorValid)) {
equal = false;
} else {
aKeyCount = 0;
equal = true;
for (key in a) {
aValue = a[key];
if (!_.has(a, key)) {
continue;
}
aKeyCount++;
if (!(_.has(b, key) && isEqual(aValue, b[key], aStack, bStack))) {
equal = false;
break;
}
}
if (equal) {
bKeyCount = 0;
for (key in b) {
bValue = b[key];
if (_.has(b, key)) {
bKeyCount++;
}
}
equal = aKeyCount === bKeyCount;
}
}
} else {
equal = _.isEqual(a, b);
}
aStack.pop();
bStack.pop();
return equal;
};
module.exports = _.extend({}, _, plus);
}).call(this);

@ -0,0 +1,23 @@
Copyright (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative
Reporters & Editors
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,22 @@
__
/\ \ __
__ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____
/\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\
\ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\
\ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/
\/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/
\ \____/
\/___/
Underscore.js is a utility-belt library for JavaScript that provides
support for the usual functional suspects (each, map, reduce, filter...)
without extending any core JavaScript objects.
For Docs, License, Tests, and pre-packed downloads, see:
http://underscorejs.org
Underscore is an open-sourced component of DocumentCloud:
https://github.com/documentcloud
Many thanks to our contributors:
https://github.com/jashkenas/underscore/contributors

@ -0,0 +1,54 @@
{
"name": "underscore",
"description": "JavaScript's functional programming helper library.",
"homepage": "http://underscorejs.org",
"keywords": [
"util",
"functional",
"server",
"client",
"browser"
],
"author": {
"name": "Jeremy Ashkenas",
"email": "jeremy@documentcloud.org"
},
"repository": {
"type": "git",
"url": "git://github.com/jashkenas/underscore.git"
},
"main": "underscore.js",
"version": "1.6.0",
"devDependencies": {
"docco": "0.6.x",
"phantomjs": "1.9.0-1",
"uglify-js": "2.4.x"
},
"scripts": {
"test": "phantomjs test/vendor/runner.js test/index.html?noglobals=true",
"build": "uglifyjs underscore.js -c \"evaluate=false\" --comments \"/ .*/\" -m --source-map underscore-min.map -o underscore-min.js",
"doc": "docco underscore.js"
},
"licenses": [
{
"type": "MIT",
"url": "https://raw.github.com/jashkenas/underscore/master/LICENSE"
}
],
"files": [
"underscore.js",
"underscore-min.js",
"LICENSE"
],
"readme": " __\n /\\ \\ __\n __ __ ___ \\_\\ \\ __ _ __ ____ ___ ___ _ __ __ /\\_\\ ____\n /\\ \\/\\ \\ /' _ `\\ /'_ \\ /'__`\\/\\ __\\/ ,__\\ / ___\\ / __`\\/\\ __\\/'__`\\ \\/\\ \\ /',__\\\n \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\ __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\ __/ __ \\ \\ \\/\\__, `\\\n \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n \\/___/ \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/ \\/____/\\/___/ \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/\n \\ \\____/\n \\/___/\n\nUnderscore.js is a utility-belt library for JavaScript that provides\nsupport for the usual functional suspects (each, map, reduce, filter...)\nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://underscorejs.org\n\nUnderscore is an open-sourced component of DocumentCloud:\nhttps://github.com/documentcloud\n\nMany thanks to our contributors:\nhttps://github.com/jashkenas/underscore/contributors\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/jashkenas/underscore/issues"
},
"_id": "underscore@1.6.0",
"dist": {
"shasum": "17906c2176b40abe48079e304631c0311efbf8ab"
},
"_from": "underscore@~1.6.0",
"_resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz"
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,48 @@
{
"name": "underscore-plus",
"version": "1.5.0",
"description": "Underscore plus additional utilities",
"licenses": [
{
"type": "MIT",
"url": "http://github.com/atom/underscore-plus/raw/master/LICENSE.md"
}
],
"main": "./lib/underscore-plus.js",
"scripts": {
"prepublish": "grunt clean coffee lint",
"test": "grunt test"
},
"repository": {
"type": "git",
"url": "https://github.com/atom/underscore-plus.git"
},
"bugs": {
"url": "https://github.com/atom/underscore-plus/issues"
},
"homepage": "http://atom.github.io/underscore-plus",
"keywords": [
"underscore"
],
"dependencies": {
"underscore": "~1.6.0"
},
"devDependencies": {
"jasmine-focused": "1.x",
"grunt-contrib-coffee": "~0.9.0",
"grunt-cli": "~0.1.8",
"grunt": "~0.4.1",
"grunt-shell": "~0.2.2",
"grunt-coffeelint": "0.0.6",
"temp": "~0.5.0",
"rimraf": "~2.1.4"
},
"readme": "# underscore-plus [![Build Status](https://travis-ci.org/atom/underscore-plus.svg?branch=master)](https://travis-ci.org/atom/underscore-plus)\n\nTakes the great [underscore](http://underscorejs.org/) library and adds a few\nmore things.\n\n## Using\n\n```sh\nnpm install underscore-plus\n```\n\n```coffeescript\n_ = require 'underscore-plus' # Has all underscore methods and more\n```\n",
"readmeFilename": "README.md",
"_id": "underscore-plus@1.5.0",
"dist": {
"shasum": "69dece800bcf9317e0c09191644e4d7d2bc3325d"
},
"_from": "underscore-plus@1.x",
"_resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.5.0.tgz"
}

@ -0,0 +1,30 @@
{
"name": "editor-stats",
"version": "0.15.0",
"main": "./lib/editor-stats",
"description": "Display a graph of keyboard and mouse usage for the last 6 hours.",
"license": "MIT",
"dependencies": {
"d3-browserify": "3.3.13",
"underscore-plus": "1.x"
},
"repository": {
"type": "git",
"url": "https://github.com/atom/editor-stats"
},
"engines": {
"atom": "*"
},
"readme": "# Editor Stats package [![Build Status](https://travis-ci.org/atom/editor-stats.svg?branch=master)](https://travis-ci.org/atom/editor-stats)\n\nView a graph of your mouse and keyboard activity for the last 6 hours.\n\nThe blue bar indicates the time of greatest activity.\n\nUse `cmd-alt-s` to open and close the graph.\n\n![](https://f.cloud.github.com/assets/671378/2262223/843b1172-9e57-11e3-9c60-8d28d542f39c.png)\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/atom/editor-stats/issues"
},
"homepage": "https://github.com/atom/editor-stats",
"_id": "editor-stats@0.15.0",
"dist": {
"shasum": "452609309c2e9670a97d4a6b52494bff4736b003"
},
"_resolved": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114614-7476-78u8m0\\package.tgz",
"_from": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114614-7476-78u8m0\\package.tgz"
}

@ -0,0 +1,39 @@
_ = require 'underscore-plus'
{$, WorkspaceView} = require 'atom'
describe "EditorStats", ->
[editorStats] = []
simulateKeyUp = (key) ->
e = $.Event "keydown", keyCode: key.charCodeAt(0)
atom.workspaceView.trigger(e)
simulateClick = ->
e = $.Event "mouseup"
atom.workspaceView.trigger(e)
beforeEach ->
atom.workspaceView = new WorkspaceView
atom.workspaceView.openSync('sample.js')
waitsForPromise ->
atom.packages.activatePackage('editor-stats').then (pack) ->
editorStats = pack.mainModule.stats
describe "when a keyup event is triggered", ->
beforeEach ->
expect(_.values(editorStats.eventLog)).not.toContain 1
expect(_.values(editorStats.eventLog)).not.toContain 2
it "records the number of times a keyup is triggered", ->
simulateKeyUp('a')
expect(_.values(editorStats.eventLog)).toContain 1
simulateKeyUp('b')
expect(_.values(editorStats.eventLog)).toContain 2
describe "when a mouseup event is triggered", ->
it "records the number of times a mouseup is triggered", ->
simulateClick()
expect(_.values(editorStats.eventLog)).toContain 1
simulateClick()
expect(_.values(editorStats.eventLog)).toContain 2

@ -0,0 +1,44 @@
.editor-stats-wrapper {
padding: 5px;
box-sizing: border-box;
border-top: 1px solid rgba(255, 255, 255, 0.05);
}
.editor-stats {
height: 50px;
width: 100%;
background: #1d1f21;
border: 1px solid rgba(0, 0, 0, 0.3);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
border-right: 1px solid rgba(255, 255, 255, 0.1);
.bar {
fill: rgba(255, 255, 255, 0.2);
shape-rendering: crispedges;
&.max {
fill: rgba(0, 163, 255, 1);
}
}
text {
font-size: 10px;
fill: rgba(255, 255, 255, 0.2);
font-family: Courier;
}
.minor text {
display: none;
}
line {
stroke: #ccc;
stroke-opacity: 0.05;
stroke-width: 1px;
shape-rendering: crispedges;
}
path.domain {
display: none;
}
}

@ -0,0 +1,3 @@
.DS_Store
npm-debug.log
node_modules

@ -0,0 +1,3 @@
## 0.1.0 - First Release
* Every feature added
* Every bug fixed

@ -0,0 +1,20 @@
Copyright (c) 2014 <Your name here>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,5 @@
# jellybeans-syntax theme
Jellybeans theme, inspired by Nanotech's jellybeans color scheme for vim, available [here](https://github.com/nanotech/jellybeans.vim)
![Screenshot](https://github.com/Trevoke/jellybeans-syntax/wiki/images/screenshot.png)

@ -0,0 +1 @@
@import "./stylesheets/base.less";

@ -0,0 +1,26 @@
{
"name": "jellybeans-syntax",
"theme": "syntax",
"version": "0.3.0",
"description": "A copy of nanotech's vim jellybeans color theme",
"repository": {
"type": "git",
"url": "https://github.com/trevoke/jellybeans-syntax"
},
"license": "MIT",
"engines": {
"atom": ">0.50.0"
},
"readme": "# jellybeans-syntax theme\n\nJellybeans theme, inspired by Nanotech's jellybeans color scheme for vim, available [here](https://github.com/nanotech/jellybeans.vim)\n\n![Screenshot](https://github.com/Trevoke/jellybeans-syntax/wiki/images/screenshot.png)\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/trevoke/jellybeans-syntax/issues"
},
"homepage": "https://github.com/trevoke/jellybeans-syntax",
"_id": "jellybeans-syntax@0.3.0",
"dist": {
"shasum": "46b9df6dd0f645e0c3292c1db20ca66f0f8eae68"
},
"_resolved": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114628-3028-1owzcen\\package.tgz",
"_from": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114628-3028-1owzcen\\package.tgz"
}

@ -0,0 +1,320 @@
@import "syntax-variables";
.editor-colors {
background-color: @syntax-background-color;
color: @syntax-text-color;
}
.editor {
background-color: @syntax-background-color;
color: @syntax-text-color;
.wrap-guide {
background-color: @syntax-wrap-guide-color;
}
.indent-guide {
color: @syntax-indent-guide-color;
}
.invisible-character {
color: @syntax-invisible-character-color;
}
.gutter {
background-color: @syntax-gutter-background-color;
color: @syntax-gutter-text-color;
.line-number {
&.cursor-line {
background-color: @syntax-gutter-background-color-selected;
color: @syntax-gutter-text-color-selected;
}
&.cursor-line-no-selection {
color: @syntax-gutter-text-color-selected;
}
}
}
.gutter .line-number.folded,
.gutter .line-number:after,
.fold-marker:after {
color: @light-gray;
}
.invisible {
color: @syntax-text-color;
}
.cursor {
color: @syntax-cursor-color;
background-color: @syntax-cursor-color;
}
.selection .region {
background-color: @syntax-selection-color;
}
}
.editor .search-results .marker .region {
background-color: transparent;
border: 1px solid @syntax-result-marker-color;
}
.editor .search-results .marker.current-result .region {
border: 1px solid @syntax-result-marker-color-selected;
}
.comment {
color: @solid-gray;
}
.entity {
&.name.type {
color: @light-orange;
}
&.other.inherited-class {
color: @green;
}
}
.keyword {
color: @dark-blue;
&.control {
color: @dark-blue;
}
&.operator {
color: @syntax-text-color;
}
&.other.special-method {
color: @blue;
}
&.other.unit {
color: @orange;
}
}
.storage {
color: @purple;
}
.constant {
color: @orange;
&.character.escape {
color: @magenta;
}
&.numeric {
color: @orange;
}
&.other.color {
color: @cyan;
}
&.other.symbol {
color: @darker-blue;
}
}
.variable {
color: @cyan;
&.interpolation {
color: darken(@red, 10%);
}
&.parameter.function {
color: @syntax-text-color;
}
}
.invalid.illegal {
background-color: @red;
color: @syntax-background-color;
}
.string {
color: @green;
&.regexp {
color: @dark-magenta;
.source.ruby.embedded {
color: @orange;
}
}
&.other.link {
color: @red;
}
}
.punctuation {
&.definition {
&.comment {
color: @solid-gray;
}
&.variable {
color: @cyan;
}
&.parameters {
color: @off-white;
}
&.string,
&.array {
color: @dark-green;
}
&.heading,
&.identity {
color: @blue;
}
&.bold {
color: @light-orange;
font-style: bold;
}
&.italic {
color: @purple;
font-style: italic;
}
}
&.section.embedded {
color: darken(@red, 10%);
}
}
.support {
&.class {
color: @light-orange;
}
&.function {
color: @cyan;
&.any-method {
color: @blue;
}
}
}
.entity {
&.name.function {
color: @yellow;
}
&.name.class, &.name.type.class {
color: @light-orange;
}
&.name.section {
color: @blue;
}
&.name.tag {
color: @red;
text-decoration: underline;
}
&.other.attribute-name {
color: @orange;
&.id {
color: @blue;
}
}
}
.meta {
&.class {
color: @light-orange;
}
&.link {
color: @orange;
}
&.require {
color: @blue;
}
&.selector {
color: @purple;
}
&.separator {
background-color: @gray;
color: @syntax-text-color;
}
}
.none {
color: @syntax-text-color;
}
.markup {
&.bold {
color: @orange;
font-style: bold;
}
&.changed {
color: @purple;
}
&.deleted {
color: @red;
}
&.italic {
color: @purple;
font-style: italic;
}
&.heading .punctuation.definition.heading {
color: @blue;
}
&.inserted {
color: @green;
}
&.list {
color: @red;
}
&.quote {
color: @orange;
}
&.raw.inline {
color: @green;
}
}
.source.gfm .markup {
-webkit-font-smoothing: auto;
&.heading {
color: @green;
}
}
.editor.mini .scroll-view {
padding-left: 1px;
}

@ -0,0 +1,30 @@
// These colors are specific to the theme. Do not use in a package!
@cyan: #c6b6fe;
@purple: #b294bb;
@green: #99ad6a;
@dark-green: #556633;
@red: #de5577;
@orange: #eeeeee;
@light-orange: #f0c674;
@yellow: #fad07a;
@magenta: #a40063;
@dark-magenta: #dd0093;
@background-color: #151515;
@text: #e8e8d3;
@black: #1c1c1c; //cursorLine, cursorColumn
@dark-cyan: #556779; //matchParen
@gray: #b0b8c0; //tabLine
@dark-gray: #9098a0; //tabLineFill
@white: #f0f0f0; // tabLineSel
@gray-brown: #606060; // pmenu
@off-white: #eeeeee; // pmenuSel
@brown: #404040; //highlight
@blue: #b0d0f0; //cursor
@darker-blue: #7597c6;
@dark-blue: #447799;
@light-brown: #605958; //linenumber
@light-gray: #ccc5c4; // cursorlinenumber
@solid-gray: #888888; // comment
@solid-light-gray: #c7c7c7; //todo

@ -0,0 +1,31 @@
@import "colors";
// This defines all syntax variables that syntax themes must implement when they
// include a syntax-variables.less file.
// General colors
@syntax-text-color: @text;
@syntax-cursor-color: @blue;
@syntax-selection-color: #404040;
@syntax-background-color: @background-color;
// Guide colors
@syntax-wrap-guide-color: lighten(@background-color, 10%);
@syntax-indent-guide-color: @dark-gray;
@syntax-invisible-character-color: @gray;
// For find and replace markers
@syntax-result-marker-color: @light-gray;
@syntax-result-marker-color-selected: white;
// Gutter colors
@syntax-gutter-text-color: @white;
@syntax-gutter-text-color-selected: @syntax-gutter-text-color;
@syntax-gutter-background-color: @dark-gray;
@syntax-gutter-background-color-selected: @gray;
// For git diff info. i.e. in the gutter
@syntax-color-renamed: @blue;
@syntax-color-added: @green;
@syntax-color-modified: @orange;
@syntax-color-removed: @red;

@ -0,0 +1,9 @@
# language-erlang package
Erlang language support for Atom.
-----
Adds syntax highlighting and snippets to Erlang files in Atom.
Copyright (c) 2014 [Jonathan Barronville](mailto:jonathan@belairlabs.com "jonathan@belairlabs.com")

File diff suppressed because it is too large Load Diff

@ -0,0 +1,53 @@
'fileTypes': [
'yaws'
]
'name': 'HTML (Erlang)'
'patterns': [
{
'begin': '(^\\s*)?(?=<erl>)'
'beginCaptures':
'1':
'name': 'punctuation.whitespace.embedded.leading.html'
'contentName': 'meta.embedded.erlang'
'end': '(?!\\G)(\\s*\\n)?'
'endCaptures':
'1':
'name': 'punctuation.whitespace.embedded.trailing.html'
'patterns': [
{
'begin': '(<)(erl)(>)'
'beginCaptures':
'0':
'name': 'meta.tag.template.html'
'1':
'name': 'punctuation.definition.tag.begin.html'
'2':
'name': 'entity.name.tag.html'
'3':
'name': 'punctuation.definition.tag.end.html'
'contentName': 'source.erlang'
'end': '((</))(erl)(>)'
'endCaptures':
'0':
'name': 'meta.tag.template.html'
'1':
'name': 'punctuation.definition.tag.begin.html'
'2':
'name': 'source.erlang'
'3':
'name': 'entity.name.tag.html'
'4':
'name': 'punctuation.definition.tag.end.html'
'patterns': [
{
'include': 'source.erlang'
}
]
}
]
}
{
'include': 'text.html.basic'
}
]
'scopeName': 'text.html.erlang.yaws'

@ -0,0 +1,25 @@
{
"description": "Erlang language support for Atom.",
"engines": {
"atom": ">0.50.0"
},
"license": "MIT",
"name": "language-erlang",
"repository": {
"type": "git",
"url": "https://github.com/jonathanmarvens/atom-language-erlang"
},
"version": "2.0.0",
"readme": "# language-erlang package\n\nErlang language support for Atom.\n\n-----\n\nAdds syntax highlighting and snippets to Erlang files in Atom.\n\nCopyright (c) 2014 [Jonathan Barronville](mailto:jonathan@belairlabs.com \"jonathan@belairlabs.com\")\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/jonathanmarvens/atom-language-erlang/issues"
},
"homepage": "https://github.com/jonathanmarvens/atom-language-erlang",
"_id": "language-erlang@2.0.0",
"dist": {
"shasum": "aebe014085be287bf333509480fd406934bc2477"
},
"_resolved": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114628-1172-uyascq\\package.tgz",
"_from": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114628-1172-uyascq\\package.tgz"
}

@ -0,0 +1,8 @@
'.source.erlang':
'editor':
'commentStart': '% '
'increaseIndentPattern': '^[^%]*(\\b(if|case|receive|after|fun|try|catch|begin|query)\\b(?!.*\\b(end)\\b.*))|(->(\\s*%.*)?$)'
'decreaseIndentPattern': '^\\s*\\b(end)\\b'
'.text.html.erlang.yaws':
'editor':
'foldEndPattern': '(?x)\n\t\t(</(?i:head|body|table|thead|tbody|tfoot|tr|div|select|fieldset|style|script|ul|ol|form|dl|erl)>\n\t\t|^\\s*-->\n\t\t|(^|\\s)\\}\n\t\t)'

@ -0,0 +1,49 @@
'.source.erlang':
'Behaviour Directive':
'prefix': 'beh'
'body': '-behaviour (${1:behaviour}).'
'Case Expression':
'prefix': 'case'
'body': 'case ${1:expression} of\n\t${2:pattern}${3: when ${4:guard}} ->\n\t\t${5:body}\nend'
'Define Directive':
'prefix': 'def'
'body': '-define (${1:macro}${2: (${3:param})}, ${4:body}).'
'Export All Directive':
'prefix': 'expall'
'body': '-compile(export_all).'
'Export Directive':
'prefix': 'exp'
'body': '-export ([${1:function}/${2:arity}]).'
'Fun Expression':
'prefix': 'fun'
'body': 'fun\n\t(${1:pattern})${2: when ${3:guard}} ->\n\t\t${4:body}\nend'
'If Expression':
'prefix': 'if'
'body': 'if\n\t${1:guard} ->\n\t\t${2:body}\nend'
'Ifdef Directive':
'prefix': 'ifdef'
'body': '-ifdef (${1:macro}).'
'Ifndef Directive':
'prefix': 'ifndef'
'body': '-ifndef (${1:macro}).'
'Import Directive':
'prefix': 'imp'
'body': '-import (${1:module}, [${2:function}/${3:arity}]).'
'Include Directive':
'prefix': 'inc'
'body': '-include ("${1:file}").'
'Module Directive':
'prefix': 'mod'
'body': '-module ($1).'
'Receive Expression':
'prefix': 'rcv'
'body': 'receive\n${1:\t${2:pattern}${3: when ${4:guard}} ->\n\t\t${5:body}\n}${6:after\n\t${7:expression} ->\n\t\t${8:body}\n}end'
'Record Directive':
'prefix': 'rec'
'body': '-record (${1:record}, {${2:field}${3: = ${4:value}}}).'
'Try Expression':
'prefix': 'try'
'body': 'try${1: ${2:expression}${3: of\n\t${4:pattern}${5: when ${6:guard}} ->\n\t\t${7:body}}}\n${8:catch\n\t${9:pattern}${10: when ${11:guard}} ->\n\t\t${12:body}}\n${13:after\n\t${14:body}}\nend'
'Undef Directive':
'prefix': 'undef'
'body': '-undef (${1:macro}).'

@ -0,0 +1,3 @@
.DS_Store
npm-debug.log
node_modules

@ -0,0 +1,8 @@
language: objective-c
notifications:
email:
on_success: never
on_failure: change
script: 'curl -s https://raw.githubusercontent.com/atom/ci/master/build-package.sh | sh'

@ -0,0 +1 @@
See the [Atom contributing guide](https://atom.io/docs/latest/contributing)

@ -0,0 +1,20 @@
Copyright (c) 2014 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,5 @@
# Sort Lines Package [![Build Status](https://travis-ci.org/atom/sort-lines.svg?branch=master)](https://travis-ci.org/atom/sort-lines)
Sorts your lines in Atom, never gets tired.
![sort-lines-demo](https://f.cloud.github.com/assets/2988/1796891/85e69ff2-6a93-11e3-89ac-31927f604592.gif)

@ -0,0 +1,40 @@
{Range} = require 'atom'
module.exports =
class RangeFinder
# Public
@rangesFor: (editor) ->
new RangeFinder(editor).ranges()
# Public
constructor: (@editor) ->
# Public
ranges: ->
selectionRanges = @selectionRanges()
if selectionRanges.length is 0
[@sortableRangeFrom(@sortableRangeForEntireBuffer())]
else
selectionRanges.map (selectionRange) =>
@sortableRangeFrom(selectionRange)
# Internal
selectionRanges: ->
@editor.getSelectedBufferRanges().filter (range) ->
not range.isEmpty()
# Internal
sortableRangeForEntireBuffer: ->
@editor.getBuffer().getRange()
# Internal
sortableRangeFrom: (selectionRange) ->
startRow = selectionRange.start.row
startCol = 0
endRow = if selectionRange.end.column == 0
selectionRange.end.row - 1
else
selectionRange.end.row
endCol = @editor.lineLengthForBufferRow(endRow)
new Range [startRow, startCol], [endRow, endCol]

@ -0,0 +1,47 @@
RangeFinder = require './range-finder'
module.exports =
activate: ->
atom.workspaceView.command 'sort-lines:sort', '.editor', ->
editor = atom.workspace.getActiveEditor()
sortLines(editor)
atom.workspaceView.command 'sort-lines:reverse-sort', '.editor', ->
editor = atom.workspace.getActiveEditor()
sortLinesReversed(editor)
atom.workspaceView.command 'sort-lines:unique', '.editor', ->
editor = atom.workspace.getActiveEditor()
uniqueLines(editor)
atom.workspaceView.command 'sort-lines:case-insensitive-sort', '.editor', ->
editor = atom.workspaceView.getActivePaneItem()
sortLinesInsensitive(editor)
sortLines = (editor) ->
sortableRanges = RangeFinder.rangesFor(editor)
sortableRanges.forEach (range) ->
textLines = editor.getTextInBufferRange(range).split("\n")
textLines.sort (a, b) -> a.localeCompare(b)
editor.setTextInBufferRange(range, textLines.join("\n"))
sortLinesReversed = (editor) ->
sortableRanges = RangeFinder.rangesFor(editor)
sortableRanges.forEach (range) ->
textLines = editor.getTextInBufferRange(range).split("\n")
textLines.sort (a, b) -> b.localeCompare(a)
editor.setTextInBufferRange(range, textLines.join("\n"))
uniqueLines = (editor) ->
sortableRanges = RangeFinder.rangesFor(editor)
sortableRanges.forEach (range) ->
textLines = editor.getTextInBufferRange(range).split("\n")
uniqued = textLines.filter (value, index, self) -> self.indexOf(value) == index
editor.setTextInBufferRange(range, uniqued.join("\n"))
sortLinesInsensitive = (editor) ->
sortableRanges = RangeFinder.rangesFor(editor)
sortableRanges.forEach (range) ->
textLines = editor.getTextInBufferRange(range).split("\n")
textLines.sort (a, b) -> a.toLowerCase().localeCompare(b.toLowerCase())
editor.setTextInBufferRange(range, textLines.join("\n"))

@ -0,0 +1,14 @@
'menu': [
{
'label': 'Edit'
'submenu': [
'label': 'Lines'
'submenu': [
{ 'label': 'Sort', 'command': 'sort-lines:sort' }
{ 'label': 'Reverse Sort', 'command': 'sort-lines:reverse-sort' }
{ 'label': 'Unique', 'command': 'sort-lines:unique' }
{ 'label': 'Sort (Case Insentivive)', 'command': 'sort-lines:case-insensitive-sort' }
]
]
}
]

@ -0,0 +1,33 @@
{
"name": "sort-lines",
"main": "./lib/sort-lines",
"version": "0.6.0",
"description": "Sorts your lines. Never gets tired.",
"activationEvents": [
"sort-lines:sort",
"sort-lines:reverse-sort",
"sort-lines:unique",
"sort-lines:case-insensitive-sort"
],
"repository": {
"type": "git",
"url": "https://github.com/atom/sort-lines"
},
"license": "MIT",
"engines": {
"atom": ">0.39.0"
},
"dependencies": {},
"readme": "# Sort Lines Package [![Build Status](https://travis-ci.org/atom/sort-lines.svg?branch=master)](https://travis-ci.org/atom/sort-lines)\n\nSorts your lines in Atom, never gets tired.\n\n![sort-lines-demo](https://f.cloud.github.com/assets/2988/1796891/85e69ff2-6a93-11e3-89ac-31927f604592.gif)\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/atom/sort-lines/issues"
},
"homepage": "https://github.com/atom/sort-lines",
"_id": "sort-lines@0.6.0",
"dist": {
"shasum": "6ac7b38f8720c27c0eb20e532555f618d1017256"
},
"_resolved": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114614-3900-113bedv\\package.tgz",
"_from": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114614-3900-113bedv\\package.tgz"
}

@ -0,0 +1,201 @@
{WorkspaceView} = require 'atom'
describe "sorting lines", ->
[activationPromise, editor, editorView] = []
sortLines = (callback) ->
editorView.trigger "sort-lines:sort"
waitsForPromise -> activationPromise
runs(callback)
sortLinesReversed = (callback) ->
editorView.trigger "sort-lines:reverse-sort"
waitsForPromise -> activationPromise
runs(callback)
uniqueLines = (callback) ->
editorView.trigger "sort-lines:unique"
waitsForPromise -> activationPromise
runs(callback)
sortLineCaseInsensitive = (callback) ->
editorView.trigger "sort-lines:case-insensitive-sort"
waitsForPromise -> activationPromise
runs(callback)
beforeEach ->
atom.workspaceView = new WorkspaceView
atom.workspaceView.openSync()
editorView = atom.workspaceView.getActiveView()
editor = editorView.getEditor()
activationPromise = atom.packages.activatePackage('sort-lines')
describe "when no lines are selected", ->
it "sorts all lines", ->
editor.setText """
Hydrogen
Helium
Lithium
"""
editor.setCursorBufferPosition([0, 0])
sortLines ->
expect(editor.getText()).toBe """
Helium
Hydrogen
Lithium
"""
it "sorts all lines, ignoring the trailing new line", ->
editor.setText """
Hydrogen
Helium
Lithium
"""
editor.setCursorBufferPosition([0, 0])
sortLines ->
expect(editor.getText()).toBe """
Helium
Hydrogen
Lithium
"""
describe "when entire lines are selected", ->
it "sorts the selected lines", ->
editor.setText """
Hydrogen
Helium
Lithium
Beryllium
Boron
"""
editor.setSelectedBufferRange([[1,0], [4,0]])
sortLines ->
expect(editor.getText()).toBe """
Hydrogen
Beryllium
Helium
Lithium
Boron
"""
describe "when partial lines are selected", ->
it "sorts the selected lines", ->
editor.setText """
Hydrogen
Helium
Lithium
Beryllium
Boron
"""
editor.setSelectedBufferRange([[1,3], [3,2]])
sortLines ->
expect(editor.getText()).toBe """
Hydrogen
Beryllium
Helium
Lithium
Boron
"""
describe "when there are multiple selection ranges", ->
it "sorts the lines in each selection range", ->
editor.setText """
Hydrogen
Helium # selection 1
Beryllium # selection 1
Carbon
Fluorine # selection 2
Aluminum # selection 2
Gallium
Europium
"""
editor.addSelectionForBufferRange([[1, 0], [3, 0]])
editor.addSelectionForBufferRange([[4, 0], [6, 0]])
sortLines ->
expect(editor.getText()).toBe """
Hydrogen
Beryllium # selection 1
Helium # selection 1
Carbon
Aluminum # selection 2
Fluorine # selection 2
Gallium
Europium
"""
describe "reversed sorting", ->
it "sorts all lines in reverse order", ->
editor.setText """
Hydrogen
Helium
Lithium
"""
editor.setCursorBufferPosition([0, 0])
sortLinesReversed ->
expect(editor.getText()).toBe """
Lithium
Hydrogen
Helium
"""
describe "uniqueing", ->
it "uniques all lines but does not change order", ->
editor.setText """
Hydrogen
Hydrogen
Helium
Lithium
Hydrogen
Hydrogen
Helium
Lithium
Hydrogen
Hydrogen
Helium
Lithium
Hydrogen
Hydrogen
Helium
Lithium
"""
editor.setCursorBufferPosition([0, 0])
uniqueLines ->
expect(editor.getText()).toBe """
Hydrogen
Helium
Lithium
"""
describe "case-insensitive sorting", ->
it "sorts all lines, ignoring case", ->
editor.setText """
Hydrogen
lithium
helium
Helium
Lithium
"""
editor.setCursorBufferPosition([0, 0])
sortLineCaseInsensitive ->
expect(editor.getText()).toBe """
helium
Helium
Hydrogen
lithium
Lithium
"""

@ -0,0 +1 @@
See the [Atom contributing guide](https://atom.io/docs/latest/contributing)

@ -0,0 +1,20 @@
Copyright (c) 2014 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,12 @@
# Spacegray Mocha UI theme
Port of the [Spacegray](http://kkga.github.io/spacegray) Sublime Text theme to Atom.
UI Theme to match base16 Mocha Syntax (http://chriskempson.github.io/base16/#mocha).
If these colors aren't to your liking, [check out my other packages!](https://atom.io/users/emilyemorehouse)
Or make a request.
Credit to [cannikin's original port](https://github.com/cannikin/spacegray-dark-ui).
![screenshot](https://s3-us-west-2.amazonaws.com/emilyemorehouse/spacegraymocha)

@ -0,0 +1,20 @@
@import "stylesheets/atom";
@import "stylesheets/buttons";
@import "stylesheets/editor";
@import "stylesheets/find-and-replace";
@import "stylesheets/git";
@import "stylesheets/lists";
@import "stylesheets/messages";
@import "stylesheets/nav";
@import "stylesheets/overlays";
@import "stylesheets/panels";
@import "stylesheets/panes";
@import "stylesheets/progress";
@import "stylesheets/sites";
@import "stylesheets/tabs";
@import "stylesheets/text";
@import "stylesheets/tips";
@import "stylesheets/tooltips";
@import "stylesheets/tree-view";
@import "stylesheets/utilities";
@import "stylesheets/zen";

@ -0,0 +1,26 @@
{
"name": "spacegray-mocha-ui",
"theme": "ui",
"version": "0.1.0",
"description": "Port of the Spacegray Sublime Text theme to Atom. UI Theme to match base16 Mocha Syntax (http://chriskempson.github.io/base16/#mocha)",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/emilyemorehouse/spacegray-mocha-ui"
},
"engines": {
"atom": ">0.50.0"
},
"readme": "# Spacegray Mocha UI theme\n\nPort of the [Spacegray](http://kkga.github.io/spacegray) Sublime Text theme to Atom.\nUI Theme to match base16 Mocha Syntax (http://chriskempson.github.io/base16/#mocha). \n\nIf these colors aren't to your liking, [check out my other packages!](https://atom.io/users/emilyemorehouse)\nOr make a request.\n\n\nCredit to [cannikin's original port](https://github.com/cannikin/spacegray-dark-ui).\n\n![screenshot](https://s3-us-west-2.amazonaws.com/emilyemorehouse/spacegraymocha)\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/emilyemorehouse/spacegray-mocha-ui/issues"
},
"homepage": "https://github.com/emilyemorehouse/spacegray-mocha-ui",
"_id": "spacegray-mocha-ui@0.1.0",
"dist": {
"shasum": "34c7b7fc289b0bbd4f993df6ceba4085ae5cc0e4"
},
"_resolved": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114628-4572-1nzcviy\\package.tgz",
"_from": "C:\\Users\\Adam\\AppData\\Local\\Temp\\d-114628-4572-1nzcviy\\package.tgz"
}

@ -0,0 +1,9 @@
@import "ui-variables";
* {
box-sizing: border-box;
}
.workspace {
background-color: @app-background-color;
}

@ -0,0 +1,55 @@
@import "ui-variables";
@import "ui-mixins";
.btn-background (@color, @hover-color, @selected-color, @text-color) {
color: @text-color-subtle;
background-color: transparent;
transition: color 0.2s;
&:hover, &:focus {
color: @text-color-subtle;
}
&.selected,
&.selected:hover {
color: @text-color-highlight;
&:hover {
}
}
}
.btn-variant (@color) {
@bg: darken(@color, 10%);
@hover: @color;
@selected: @color;
.btn-background(@bg, @hover, @selected, @text-color-highlight);
}
.btn {
.btn-background(@button-background-color, @button-background-color-hover, @button-background-color-selected, @text-color);
&:active {
box-shadow: none;
-webkit-box-shadow: none;
}
}
.btn.btn-primary {
.btn-variant(@background-color-info);
}
.btn.btn-info {
.btn-variant(@background-color-info);
}
.btn.btn-success {
.btn-variant(@background-color-success);
}
.btn.btn-warning {
.btn-variant(@background-color-warning);
}
.btn.btn-error {
.btn-variant(@background-color-error);
}
.caret {
border-top: 5px solid #fff;
margin-top: -1px;
}

@ -0,0 +1,18 @@
@import "ui-variables";
@import "ui-mixins";
@import "octicon-mixins";
.dropdown-menu {
background-color: @overlay-background-color;
border-radius: @component-border-radius;
padding: 0;
> li > a {
.text(normal);
}
> li > a:hover {
.text(highlight);
background-color: @background-color-highlight;
}
}

@ -0,0 +1,35 @@
@import "ui-variables";
@import "ui-mixins";
@-webkit-keyframes highlight {
from { background-color: rgba(100, 255, 100, 0.7); }
to { background-color: null; }
}
.editor {
font-family: @font-family-code;
&.mini {
color: @text-color-highlight;
background-color: @input-background-color;
border-radius: @component-border-radius;
padding-left: @component-padding/2;
.placeholder-text {
color: @text-color-subtle;
}
.cursor { border-color: #fff; }
.selection .region { background-color: lighten(@input-background-color, 10%); }
}
&.editor-colors.mini.is-focused {
.selection .region { background-color: lighten(@app-background-color, 5%); }
transition: background-color 0.1s
}
.highlighted.selection .region {
-webkit-animation-name: highlight;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: 1;
}
}

@ -0,0 +1,15 @@
.btn-group-find, .btn-group-replace, .btn-group-replace-all {
.btn {
color: @0C;
&:hover {
color: @07;
}
}
}
.project-find .highlight-info {
color: @0A;
background-color: @-00;
border-radius: 2px;
padding: 3px 1px;
}

@ -0,0 +1,9 @@
@import "ui-mixins";
@import "ui-variables";
.status { .text(normal); }
.status-added { .text(info); }
.status-ignored { .text(subtle); }
.status-modified { .text(warning); }
.status-removed { .text(error); }
.status-renamed { .text(success); }

@ -0,0 +1,123 @@
@import "ui-variables";
@import "ui-mixins";
@import "octicon-mixins";
.list-group, .list-tree {
li:not(.list-nested-item),
li.list-nested-item > .list-item {
.text(normal);
}
.generate-list-item-text-color(@class) {
li:not(.list-nested-item).text-@{class},
li.list-nested-item.text-@{class} > .list-item {
.text(@class);
}
}
.generate-list-item-text-color(subtle);
.generate-list-item-text-color(info);
.generate-list-item-text-color(success);
.generate-list-item-text-color(warning);
.generate-list-item-text-color(error);
.generate-list-item-text-color(selected);
.generate-list-item-status-color(@color, @status) {
li:not(.list-nested-item).status-@{status},
li.list-nested-item.status-@{status} > .list-item {
color: @color;
}
}
.generate-list-item-status-color(@text-color-subtle, ignored);
.generate-list-item-status-color(@text-color-added, added);
.generate-list-item-status-color(@text-color-renamed, renamed);
.generate-list-item-status-color(@text-color-modified, modified);
.generate-list-item-status-color(@text-color-removed, removed);
li:not(.list-nested-item).selected,
li.list-nested-item.selected > .list-item {
.text(selected);
}
}
.select-list ol.list-group,
&.select-list ol.list-group {
li.two-lines {
.secondary-line { color: @text-color-subtle; }
&.selected .secondary-line {
color: @text-color-subtle;
text-shadow: none;
}
}
// We want to highlight the background of the list items because we dont
// know their size.
li.selected {
background-color: @background-color-selected;
&:before{ display: none; }
}
&.mark-active{
@active-icon-size: 14px;
// pad in front of the text where the icon would be We'll pad the non-
// active items with a 'fake' icon so other classes can pad the item
// without worrying about the icon padding.
li:before {
content: '';
background-color: transparent;
position: static;
display: inline-block;
left: auto; right: auto;
height: @active-icon-size;
width: @active-icon-size;
}
> li:not(.active):before {
margin-right: @component-icon-padding;
}
li.active {
.octicon(check, @active-icon-size);
&:before {
margin-right: @component-icon-padding;
color: @text-color-success;
}
}
}
}
.select-list.popover-list {
background-color: @overlay-background-color;
padding: @component-padding/2;
border-radius: @component-border-radius;
border: 1px solid @overlay-border-color;
.editor {
margin-bottom: @component-padding/2;
}
.list-group li {
padding-left: @component-padding/2;
}
}
.ui-sortable {
li {
line-height: 2.5;
}
// For sortable lists in the settings view
li.ui-sortable-placeholder {
visibility: visible !important;
background-color: darken(@pane-item-background-color, 10%);
}
}
li.ui-draggable-dragging, li.ui-sortable-helper {
line-height: @component-line-height;
height: @component-line-height;
border: 0;
border-radius: 0;
list-style: none;
padding: 0 @component-padding;
background: @background-color-highlight;;
}

@ -0,0 +1,6 @@
@import "ui-variables";
ul.background-message {
font-weight: bold;
color: rgba(0, 0, 0, .2);
}

@ -0,0 +1,27 @@
@import "ui-variables";
.nav-tabs {
border-bottom: 1px solid @base-border-color;
li {
a,
&.active a {
border: none;
margin-right: 0px;
margin-bottom: 1px;
}
a:hover,
&.active a,
&.active a:hover {
background-color: @background-color-highlight;
border: none;
color: @text-color-selected;
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
}
&.active a {
background-color: @tab-background-color-active;
}
}
}

@ -0,0 +1,38 @@
@import "ui-variables";
.overlay {
color: @text-color-subtle;
background-color: @overlay-background-color;
padding: @component-padding;
border-radius: @component-border-radius;
.editor.mini {
margin-bottom: @component-padding;
}
.select-list ol.list-group,
&.select-list ol.list-group {
background-color: lighten(@overlay-background-color, 3%);
li {
padding: @component-padding;
&.two-lines { padding: @component-padding/2 @component-padding; }
.status.icon {
float: right;
margin-left: @component-icon-padding;
&:before {
margin-right: 0;
}
}
&.selected {
.status.icon {
color: @text-color-selected;
}
}
}
}
}

@ -0,0 +1,44 @@
@import "ui-mixins";
@import "ui-variables";
@import "buttons";
.panel {
&.bordered {
border-radius: @component-border-radius;
}
}
.tool-panel {
.text(normal);
position: relative;
background-color: @tool-panel-background-color;
}
.inset-panel {
position: relative;
background-color: @inset-panel-background-color;
}
.is-blurred {
.tool-panel,
.inset-panel {
}
}
.panel-heading {
.text(normal);
background-color: transparent;
.btn {
padding-left: 8px;
padding-right: 8px;
@bg: lighten(@button-background-color, 10%);
@hover: lighten(@button-background-color-hover, 10%);
@selected: lighten(@button-background-color-selected, 10%);
@text: lighten(@text-color, 10%);
.btn-background(@bg, @hover, @selected, @text);
}
}

@ -0,0 +1,63 @@
@import "ui-mixins";
@import "ui-variables";
@import "buttons";
.pane-item {
.panel {
border-color: fadeout(@inset-panel-border-color, 30%);
}
}
.panes {
.pane {
background-color: @editor-background-color;
.item-views .pane-item {
background-color: @editor-background-color;
font-family: @font-family-code;
font-size: @font-size;
}
&:focus {
background-color: @app-background-color;
}
}
.pane-row > * {
border-right: 1px solid @pane-item-border-color;
&:last-child { border-right: none; }
}
.pane-column > * {
border-bottom: 1px solid @pane-item-border-color;
&:last-child { border-bottom: none; }
}
}
.preview-pane {
.list-tree li.list-nested-item > .list-item {
color: @05;
}
.list-tree li:not(.list-nested-item) {
color: @05;
}
.highlight-info {
color: @05;
background-color: @00;
border: 1px solid @0A;
border-radius: 3px;
padding: 2px 1px;
}
.preview-count {
.highlight-info {
color: @0A;
background-color: @00;
border: none;
}
}
.results-view .line-number {
color: @09;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save