diff --git a/keymaps/php-debug.cson b/keymaps/php-debug.cson
index 5bafe29..257ec9e 100644
--- a/keymaps/php-debug.cson
+++ b/keymaps/php-debug.cson
@@ -34,3 +34,7 @@
'alt-f6': 'php-debug:stepOver'
'alt-f7': 'php-debug:stepIn'
'alt-f8': 'php-debug:stepOut'
+
+'atom-workspace .php-debug-console atom-text-editor':
+ 'alt-up': 'php-debug:navigatePreviousConsoleCommand'
+ 'alt-down': 'php-debug:navigateNextConsoleCommand'
diff --git a/lib/console/php-debug-console-view.coffee b/lib/console/php-debug-console-view.coffee
index e712bf8..5f0c228 100644
--- a/lib/console/php-debug-console-view.coffee
+++ b/lib/console/php-debug-console-view.coffee
@@ -23,6 +23,8 @@ class PhpDebugConsoleView extends ScrollView
super
@GlobalContext = params.context
@visible = false
+ @stack = []
+ @curCommand = -1
curHeight = atom.config.get('php-debug.currentConsoleHeight')
if (curHeight)
this.element.style.height = curHeight
@@ -86,7 +88,6 @@ class PhpDebugConsoleView extends ScrollView
@visible
setVisible: (@visible) =>
-
if @visible
@panel.show()
else
@@ -97,9 +98,12 @@ class PhpDebugConsoleView extends ScrollView
expression = @consoleCommandLine
.getModel()
.getText()
+ # enqueue entered command, limit stack size and update index
+ @stack.push expression
+ @stack.shift() if @stack.length > 20
+ @curCommand = @stack.length
@GlobalContext.notifyConsoleMessage(">" + expression)
@GlobalContext.getCurrentDebugContext()?.evalExpression(expression)
-
@consoleCommandLine
.getModel()
.setText('')
@@ -107,3 +111,14 @@ class PhpDebugConsoleView extends ScrollView
isEqual: (other) ->
other instanceof PhpDebugConsoleView
+
+ prevCommand: () ->
+ return unless @stack.length
+ @curCommand -= 1 if @curCommand > 0
+ @consoleCommandLine.getModel().setText(@stack[@curCommand])
+
+ nextCommand: () ->
+ return unless @stack.length
+ len = @stack.length
+ @curCommand += 1 if @curCommand < len
+ @consoleCommandLine.getModel().setText(if @curCommand < len then @stack[@curCommand] else '')
diff --git a/lib/context/context-variable-list-view.coffee b/lib/context/context-variable-list-view.coffee
index 69067ec..0450241 100644
--- a/lib/context/context-variable-list-view.coffee
+++ b/lib/context/context-variable-list-view.coffee
@@ -8,11 +8,24 @@ class ContextVariableListView extends View
@content: (params) ->
dataname = if params.name then params.name else ''
dataname = if !!params.parent then params.parent + '.' + dataname else dataname
+ nameIsNumeric = /^\d+$/.test(params.name)
+ label = params.name
+ if !params.parent # root taxonomy (Locals, etc.)
+ labelClass = 'syntax--type'
+ else if params.parent.indexOf('.') == -1 # variable
+ labelClass = 'syntax--variable'
+ else # array key, object property
+ labelClass = "syntax--property #{if nameIsNumeric then 'syntax--constant syntax--numeric' else 'syntax--string'}"
+ label = '"' + params.name + '"'
+ valueClass = switch params.type
+ when 'array' then 'syntax--support syntax--function'
+ when 'object' then 'syntax--entity syntax--name syntax--type'
+ else ''
@li class: "context-variable-list-view", =>
@details 'data-name': dataname, =>
@summary =>
- @span class: 'variable php', params.name
- @span class: 'type php', params.summary
+ @span class: "variable php syntax--php #{labelClass}", label
+ @span class: "type php syntax--php syntax--#{params.type} #{valueClass}", params.summary
@ul outlet: "contextVariableList"
initialize: ({@variables,@autoopen,@parent,@name,@openpaths}) ->
@@ -25,5 +38,3 @@ class ContextVariableListView extends View
if @variables
for variable in @variables
@contextVariableList.append(new ContextVariableView({variable:variable, parent: path,openpaths:@openpaths}))
-
-
diff --git a/lib/context/context-variable-view.coffee b/lib/context/context-variable-view.coffee
index e5d4e97..ea98728 100644
--- a/lib/context/context-variable-view.coffee
+++ b/lib/context/context-variable-view.coffee
@@ -4,6 +4,7 @@ helpers = require '../helpers'
module.exports =
class ContextVariableView extends View
+
@content: =>
@li class: 'native-key-bindings', =>
@div class: 'native-key-bindings', tabindex: -1, outlet: 'variableView'
@@ -12,12 +13,28 @@ class ContextVariableView extends View
@render()
renderScalar: ({label,value}) ->
- "#{label}#{value}"
+ labelIsNumeric = /^\d+$/.test(label)
+ if @parent == 'User defined constants'
+ labelClass = "variable php syntax--php syntax--constant"
+ else
+ labelClass = 'variable php syntax--php ' + switch label[0]
+ when '$' then 'syntax--variable'
+ else "syntax--property #{if labelIsNumeric then 'syntax--constant syntax--numeric' else 'syntax--string'}"
+ label = '"'+label+'"' if !labelIsNumeric and label[0] != '$'
+ valueClass = "type php syntax--php syntax--#{@variable.type} " + switch @variable.type
+ when 'bool', 'null', 'numeric' then 'syntax--constant'
+ when 'object' then 'syntax--entity syntax--name syntax--type'
+ when 'uninitialized' then 'syntax--comment'
+ else ''
+ "#{label}#{value}"
render: ->
ContextVariableListView = require "./context-variable-list-view"
label = @variable.label
openChildren = false
+ mapValue = {
+ bool: { '0': 'false', '1': 'true' },
+ }
if @openpaths?
for open in @openpaths
if !!@parent
@@ -34,7 +51,7 @@ class ContextVariableView extends View
when 'numeric'
@variableView.append(@renderScalar({label: label, value:@variable.value}))
when 'bool'
- @variableView.append(@renderScalar({label: label, value:@variable.value}))
+ @variableView.append(@renderScalar({label: label, value: mapValue.bool[@variable.value]}))
when 'uninitialized'
@variableView.append(@renderScalar({label:label, value:"?"}))
when 'error'
@@ -42,14 +59,30 @@ class ContextVariableView extends View
when 'null'
@variableView.append(@renderScalar({label: label, value: "null"}))
when 'array'
- summary ="array["+@variable.length+"]"
- @variableView.append(new ContextVariableListView({name: label, summary: summary, variables: @variable.value, autoopen: openChildren,parent:@parent,openpaths:@openpaths}))
+ summary ="array["+(@variable.length || @variable.value.length)+"]"
+ @variableView.append(new ContextVariableListView({
+ name: label,
+ summary: summary,
+ variables: @variable.value,
+ autoopen: openChildren,
+ parent:@parent,
+ openpaths:@openpaths,
+ type: @variable.type,
+ }))
when 'object'
summary ="object"
if @variable.className
summary += " ["+@variable.className+"]"
properties = @variable.value
- @variableView.append(new ContextVariableListView({name:label, summary: summary, variables: properties, autoopen: openChildren, parent:@parent,openpaths:@openpaths}))
+ @variableView.append(new ContextVariableListView({
+ name:label,
+ summary: summary,
+ variables: properties,
+ autoopen: openChildren,
+ parent:@parent,
+ openpaths:@openpaths,
+ type: @variable.type,
+ }))
when 'resource'
@variableView.append(@renderScalar({label:label, value: "\""+helpers.escapeHtml(@variable.value)+"\""}))
else
diff --git a/lib/context/context-view.coffee b/lib/context/context-view.coffee
index 2f5edf6..25e9b7c 100644
--- a/lib/context/context-view.coffee
+++ b/lib/context/context-view.coffee
@@ -20,4 +20,23 @@ class ContextView extends View
openChildren = true
break
+ cbDeepNaturalSort = (a,b) ->
+ aIsNumeric = /^\d+$/.test(a.name)
+ bIsNumeric = /^\d+$/.test(b.name)
+ # cannot exist two equal keys, so skip case of returning 0
+ if aIsNumeric && bIsNumeric # order numbers
+ return if (parseInt(a.name, 10) < parseInt(b.name, 10)) then -1 else 1
+ else if !aIsNumeric && !bIsNumeric # order strings
+ return if (a.name < b.name) then -1 else 1
+ else # string first (same behavior that PHP's `ksort`)
+ return if aIsNumeric then 1 else -1
+
+ fnWalkVar = (contextVar) ->
+ if Array.isArray(contextVar)
+ for item in contextVar
+ if Array.isArray(item.value)
+ fnWalkVar(item.value)
+ contextVar.sort(cbDeepNaturalSort)
+
+ fnWalkVar(@context.context.variables)
@contextListView.append(new ContextVariableListView( {name: @context.name, summary: null, variables: @context.context.variables, autoopen: openChildren, openpaths:@autoopen, parent:null}))
diff --git a/lib/engines/dbgp/dbgp-instance.coffee b/lib/engines/dbgp/dbgp-instance.coffee
index 33bf34d..8fba0b8 100644
--- a/lib/engines/dbgp/dbgp-instance.coffee
+++ b/lib/engines/dbgp/dbgp-instance.coffee
@@ -422,10 +422,10 @@ class DbgpInstance extends DebugContext
type: variable.$.type
}
- if variable.$.fullname?
- datum.label = variable.$.fullname
- else if variable.$.name?
+ if variable.$.name?
datum.label = variable.$.name
+ else if variable.$.fullname?
+ datum.label = variable.$.fullname
switch variable.$.type
when "string"
diff --git a/lib/php-debug.coffee b/lib/php-debug.coffee
index f9a37c1..fb773c9 100644
--- a/lib/php-debug.coffee
+++ b/lib/php-debug.coffee
@@ -131,6 +131,8 @@ module.exports = PhpDebug =
@subscriptions.add atom.commands.add 'atom-workspace', 'php-debug:stepOut': => @stepOut()
@subscriptions.add atom.commands.add 'atom-workspace', 'php-debug:clearAllBreakpoints': => @clearAllBreakpoints()
@subscriptions.add atom.commands.add 'atom-workspace', 'php-debug:clearAllWatchpoints': => @clearAllWatchpoints()
+ @subscriptions.add atom.commands.add 'atom-workspace', 'php-debug:navigatePreviousConsoleCommand': => @navigatePreviousConsoleCommand()
+ @subscriptions.add atom.commands.add 'atom-workspace', 'php-debug:navigateNextConsoleCommand': => @navigateNextConsoleCommand()
@subscriptions.add atom.workspace.addOpener (filePath) =>
switch filePath
when PhpDebugContextUri
@@ -298,6 +300,7 @@ module.exports = PhpDebug =
if bp.getPath() == path && bp.getLine() == line
breakpoint = bp
break
+ return if !breakpoint
@settingsView = new BreakpointSettingsView({breakpoint:breakpoint,context:@GlobalContext})
@settingsView.attach()
@@ -438,3 +441,9 @@ module.exports = PhpDebug =
marker = @addBreakpointMarker(line, editor)
breakpoint.setMarker(marker)
@GlobalContext.addBreakpoint breakpoint
+
+ navigatePreviousConsoleCommand: ->
+ @consoleView.prevCommand()
+
+ navigateNextConsoleCommand: ->
+ @consoleView.nextCommand()