Pull out command-logger package to separate repo

This commit is contained in:
Kevin Sawicki
2013-08-12 18:14:51 -07:00
parent 01fee754f7
commit d2cf652a0b
6 changed files with 1 additions and 302 deletions

View File

@@ -69,6 +69,7 @@
"yaml-tmbundle": "1.0.0",
"archive-view": "0.1.0",
"autoflow": "0.1.0",
"command-logger": "0.1.0",
"spell-check": "0.1.0",
"terminal": "0.3.0"
},

View File

@@ -1,186 +0,0 @@
{$$$} = require 'space-pen'
ScrollView = require 'scroll-view'
_ = require 'underscore'
humanize = require 'humanize-plus'
module.exports =
class CommandLoggerView extends ScrollView
@content: (rootView) ->
@div class: 'command-logger', tabindex: -1, =>
@h4 class: 'category-header', outlet: 'categoryHeader'
@h5 class: 'category-summary', outlet: 'categorySummary'
@div class: 'tree-map', outlet: 'treeMap'
eventLog: null
ignoredEvents: [
'core:backspace'
'core:cancel'
'core:confirm'
'core:delete'
'core:move-down'
'core:move-left'
'core:move-right'
'core:move-up'
'editor:newline'
'tree-view:directory-modified'
]
initialize: ->
super
@command 'core:cancel', => @detach()
@on 'blur', => @detach() unless document.activeElement is this[0]
toggle: (@eventLog={}) ->
if @hasParent()
@detach()
else
@attach()
createNodes: ->
categories = {}
for eventName, details of @eventLog
continue if _.contains(@ignoredEvents, eventName)
categoryStart = eventName.indexOf(':')
if categoryStart is -1
categoryName = 'Uncategorized'
else
categoryName = _.humanizeEventName(eventName.substring(0, categoryStart))
category = categories[categoryName]
unless category
category =
name: _.humanizeEventName(categoryName)
children: []
categories[categoryName] = category
category.children.push
name: "#{_.humanizeEventName(eventName.substring(categoryStart + 1))} #{details.count}"
size: details.count
_.toArray(categories)
createNodeContent: (node) ->
$$$ ->
@div style: "height:#{node.dy - 1}px;width:#{node.dx - 1}px", =>
@span node.name
updateCategoryHeader: (node) ->
@categoryHeader.text("#{node.name} Commands")
reduceRunCount = (previous, current) ->
if current.size?
previous + current.size
else if current.children?.length > 0
current.children.reduce(reduceRunCount, previous)
else
previous
runCount = node.children.reduce(reduceRunCount, 0)
reduceCommandCount = (previous, current) ->
if current.children?.length > 0
current.children.reduce(reduceCommandCount, previous)
else
previous + 1
commandCount = node.children.reduce(reduceCommandCount, 0)
commandText = "#{humanize.intcomma(commandCount)} #{humanize.pluralize(commandCount, 'command')}"
invocationText = "#{humanize.intcomma(runCount)} #{humanize.pluralize(runCount, 'invocation')}"
@categorySummary.text("#{commandText}, #{invocationText}")
updateTreeMapSize: ->
@treeMap.width(@width() - 20)
@treeMap.height(@height() - @categoryHeader.outerHeight() - @categorySummary.outerHeight() - 20)
addTreeMap: ->
root =
name: 'All'
children: @createNodes()
node = root
@treeMap.empty()
@updateCategoryHeader(root)
@updateTreeMapSize()
w = @treeMap.width()
h = @treeMap.height()
d3 = require 'd3'
x = d3.scale.linear().range([0, w])
y = d3.scale.linear().range([0, h])
color = d3.scale.category20()
zoom = (d) =>
@updateCategoryHeader(d)
kx = w / d.dx
ky = h / d.dy
x.domain([d.x, d.x + d.dx])
y.domain([d.y, d.y + d.dy])
t = svg.selectAll('g.node')
.transition()
.duration(750)
.attr('transform', (d) -> "translate(#{x(d.x)},#{y(d.y)})")
t.select('rect')
.attr('width', (d) -> kx * d.dx - 1)
.attr('height', (d) -> ky * d.dy - 1)
t.select('.foreign-object')
.attr('width', (d) -> kx * d.dx - 1)
.attr('height', (d) -> ky * d.dy - 1)
t.select('.command-logger-node-text div')
.attr('style', (d) -> "height:#{ky * d.dy - 1}px;width:#{kx * d.dx - 1}px")
node = d
d3.event.stopPropagation()
treemap = d3.layout.treemap()
.round(false)
.size([w, h])
.sticky(true)
.value((d) -> d.size)
svg = d3.select('.command-logger .tree-map')
.append('div')
.style('width', "#{w}px")
.style('height', "#{h}px")
.append('svg')
.attr('width', w)
.attr('height', h)
.append('g')
.attr('transform', 'translate(.5,.5)')
nodes = treemap.nodes(root).filter((d) -> not d.children)
cell = svg.selectAll('g')
.data(nodes)
.enter()
.append('g')
.attr('class', 'node')
.attr('transform', (d) -> "translate(#{d.x},#{d.y})")
.on('click', (d) -> if node is d.parent then zoom(root) else zoom(d.parent))
cell.append('rect')
.attr('width', (d) -> d.dx - 1)
.attr('height', (d) -> d.dy - 1)
.style('fill', (d) -> color(d.parent.name))
cell.append('foreignObject')
.attr('width', (d) -> d.dx - 1)
.attr('height', (d) -> d.dy - 1)
.attr('class', 'foreign-object')
.append('xhtml:body')
.attr('class', 'command-logger-node-text')
.html((d) => @createNodeContent(d))
d3.select('.command-logger').on('click', -> zoom(root))
attach: ->
rootView.append(this)
@addTreeMap()
@focus()
detach: ->
return if @detaching
@detaching = true
super
rootView.focus()
@detaching = false

View File

@@ -1,41 +0,0 @@
$ = require 'jquery'
module.exports =
eventLog: {}
commandLoggerView: null
originalTrigger: null
activate: (state) ->
@eventLog = state.eventLog ? {}
rootView.command 'command-logger:clear-data', => @eventLog = {}
rootView.command 'command-logger:toggle', => @createView().toggle(@eventLog)
registerTriggeredEvent = (eventName) =>
eventNameLog = @eventLog[eventName]
unless eventNameLog
eventNameLog =
count: 0
name: eventName
@eventLog[eventName] = eventNameLog
eventNameLog.count++
eventNameLog.lastRun = new Date().getTime()
trigger = $.fn.trigger
@originalTrigger = trigger
$.fn.trigger = (event) ->
eventName = event.type ? event
registerTriggeredEvent(eventName) if $(this).events()[eventName]
trigger.apply(this, arguments)
deactivate: ->
$.fn.trigger = @originalTrigger if @originalTrigger?
@commandLoggerView = null
@eventLog = {}
serialize: ->
{@eventLog}
createView: ->
unless @commandLoggerView?
CommandLoggerView = require './command-logger-view'
@commandLoggerView = new CommandLoggerView
@commandLoggerView

View File

@@ -1,2 +0,0 @@
'main': './lib/command-logger'
'description': 'View a heat map of your Atom activity. Open from the command palette.'

View File

@@ -1,53 +0,0 @@
RootView = require 'root-view'
CommandLogger = require 'command-logger/lib/command-logger-view'
describe "CommandLogger", ->
[commandLogger, editor] = []
beforeEach ->
window.rootView = new RootView
rootView.open('sample.js')
commandLogger = atom.activatePackage('command-logger').mainModule
commandLogger.eventLog = {}
editor = rootView.getActiveView()
describe "when a command is triggered", ->
it "records the number of times the command is triggered", ->
expect(commandLogger.eventLog['core:backspace']).toBeUndefined()
editor.trigger 'core:backspace'
expect(commandLogger.eventLog['core:backspace'].count).toBe 1
editor.trigger 'core:backspace'
expect(commandLogger.eventLog['core:backspace'].count).toBe 2
it "records the date the command was last triggered", ->
expect(commandLogger.eventLog['core:backspace']).toBeUndefined()
editor.trigger 'core:backspace'
lastRun = commandLogger.eventLog['core:backspace'].lastRun
expect(lastRun).toBeGreaterThan 0
start = new Date().getTime()
waitsFor ->
new Date().getTime() > start
runs ->
editor.trigger 'core:backspace'
expect(commandLogger.eventLog['core:backspace'].lastRun).toBeGreaterThan lastRun
describe "when the data is cleared", ->
it "removes all triggered events from the log", ->
expect(commandLogger.eventLog['core:backspace']).toBeUndefined()
editor.trigger 'core:backspace'
expect(commandLogger.eventLog['core:backspace'].count).toBe 1
rootView.trigger 'command-logger:clear-data'
expect(commandLogger.eventLog['core:backspace']).toBeUndefined()
describe "when an event is ignored", ->
it "does not create a node for that event", ->
commandLoggerView = commandLogger.createView()
commandLoggerView.ignoredEvents.push 'editor:delete-line'
editor.trigger 'editor:delete-line'
commandLoggerView.eventLog = commandLogger.eventLog
nodes = commandLoggerView.createNodes()
for node in nodes
continue unless node.name is 'Editor'
for child in node.children
expect(child.name.indexOf('Delete Line')).toBe -1

View File

@@ -1,20 +0,0 @@
.command-logger {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
overflow: auto;
z-index: 99;
}
.command-logger-node-text div {
display: table-cell;
vertical-align: middle;
text-align: center;
cursor: pointer;
}
.command-logger-node-text span {
-webkit-user-select: none;
}