parent
ef7d28aa1f
commit
3f787f3031
@ -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"
|
||||
}
|
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 @@
|
||||
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://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
|
||||
```
|
498
.atom/packages/editor-stats/node_modules/underscore-plus/lib/underscore-plus.js
generated
vendored
498
.atom/packages/editor-stats/node_modules/underscore-plus/lib/underscore-plus.js
generated
vendored
@ -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, '"').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);
|
23
.atom/packages/editor-stats/node_modules/underscore-plus/node_modules/underscore/LICENSE
generated
vendored
23
.atom/packages/editor-stats/node_modules/underscore-plus/node_modules/underscore/LICENSE
generated
vendored
@ -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
1343
.atom/packages/editor-stats/node_modules/underscore-plus/node_modules/underscore/underscore.js
generated
vendored
1343
.atom/packages/editor-stats/node_modules/underscore-plus/node_modules/underscore/underscore.js
generated
vendored
File diff suppressed because it is too large
Load Diff
@ -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…
Reference in new issue