Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Implement a modal goto panel #34

Merged
merged 11 commits into from
Apr 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions lib/gotodef.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
{$$, SelectListView} = require 'atom-space-pen-views'
fuzzaldrinPlus = require 'fuzzaldrin-plus'

# ## GoToDef-Panel
#
# `goto` either takes a `symbolTable` as its argument, or a Promise which returns a
# `symbolTable`.
#
# A `symbolTable` is specified by having the following fields:
#
# - `symbolTable.error`: Boolean. If true, the contents of `result.items` will
# be shown as an error.
#
# - `symbolTable.items` - Array that contains objects with the fields
# - `.text` - Displayed text, searchable.
# - `.file` - File in which this method is defined, not displayed.
# - `.line` - Line of definition.
# - `.dispfile` - Humanized file path, displayed.
#
# or a plain text string if `symbolTable.error` is true.


module.exports =
goto: (symbolTableOrPromise) ->
@view ?= new GotoView()

# this allows either a promise or a symbolTable as the input
promise = Promise.resolve symbolTableOrPromise

promise.then (symbolTable) =>
if symbolTable.error
@view.setError symbolTable.items
@view.show()
else if symbolTable.items.length == 1
GotoView.openItem symbolTable.items[0]
else if symbolTable.items.length > 1
@view.setItems symbolTable.items
@view.show()

class GotoView extends SelectListView
initialize: ->
super
@panel = atom.workspace.addModalPanel(item: this, visible: false)
@addClass('command-palette')
@addClass('gotodef-panel')

destroy: ->
@cancel()
@panel.destroy()

# Create the view for one item.
viewForItem: ({text, dispfile, line}) ->
# the highlighting is taken verbatim from https://github.com/atom/command-palette
filterQuery = @getFilterQuery()
matches = fuzzaldrinPlus.match(text, filterQuery)

$$ ->
highlighter = (command, matches, offsetIndex) =>
lastIndex = 0
matchedChars = [] # Build up a set of matched chars to be more semantic

for matchIndex in matches
matchIndex -= offsetIndex
continue if matchIndex < 0 # If marking up the basename, omit command matches
unmatched = command.substring(lastIndex, matchIndex)
if unmatched
@span matchedChars.join(''), class: 'character-match' if matchedChars.length
matchedChars = []
@text unmatched
matchedChars.push(command[matchIndex])
lastIndex = matchIndex + 1

@span matchedChars.join(''), class: 'character-match' if matchedChars.length

# Remaining characters are plain text
@text command.substring(lastIndex)

@li class: 'two-lines', =>
@div class: 'primary-line', -> highlighter(text, matches, 0)
@div dispfile + ":" + line, class: 'secondary-line'

# Only `item.text` is searchable.
getFilterKey: -> 'text'

# Show the goto-panel and store the previously focused element.
show: () ->
@storeFocusedElement()
@panel.show()
@focusFilterEditor()

hide: () ->
@panel?.hide()

# Jump to `item.file` at line `item.line`, when an item was selected.
confirmed: (item) ->
GotoView.openItem item
@hide()

# Return to previously focused element when the modal panel is cancelled.
cancelled: ->
@hide()

@openItem: (item) ->
atom.workspace.open item.file,
initialLine: item.line
2 changes: 2 additions & 0 deletions lib/ink.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Console = require './console/console'
PlotPane = require './plots/pane'
Workspace = require './workspace/workspace'
tree = require './tree'
goto = require './gotodef'

module.exports = Ink =
activate: ->
Expand Down Expand Up @@ -38,3 +39,4 @@ module.exports = Ink =
PlotPane: PlotPane
highlights: highlights
tree: tree
goto: goto
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"atom": ">=1.0.0 <2.0.0"
},
"dependencies": {
"atom-space-pen-views": "^2.0.0"
"atom-space-pen-views": "^2.0.0",
"fuzzaldrin-plus": "^0.1.0"
},
"providedServices": {
"ink": {
Expand Down
15 changes: 15 additions & 0 deletions styles/ink.less
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,18 @@ atom-text-editor::shadow {
ink-console .ink.tree > .icon {
position: absolute;
}

.gotodef-panel {
.two-lines {
padding: 0.2em 0.75em 0.2em 1em !important;
.primary-line, .secondary-line {
line-height: 1.8em;
}
}
.error-message {
color: @text-color-error;
}
.character-match {
font-weight: bold;
}
}