diff --git a/extensions/filefinder/filefinder-pane.coffee b/extensions/filefinder/filefinder-pane.coffee
deleted file mode 100644
index 93cc68e7a..000000000
--- a/extensions/filefinder/filefinder-pane.coffee
+++ /dev/null
@@ -1,102 +0,0 @@
-$ = require 'jquery'
-_ = require 'underscore'
-
-File = require 'fs'
-Pane = require 'pane'
-
-jQuery = $
-Modal = require 'modal'
-
-require 'filefinder/stringscore'
-
-module.exports =
-class FilefinderPane extends Pane
- html: require "filefinder/filefinder.html"
-
- constructor: (@filefinder) ->
- $('#filefinder input').live 'keydown', @onKeydown
- @modal = new Modal @html
-
- onKeydown: (e) =>
- keys = up: 38, down: 40, enter: 13
-
- if e.keyCode is keys.enter
- @openSelected()
- false
- else if e.keyCode is keys.up
- @moveUp()
- else if e.keyCode is keys.down
- @moveDown()
- else
- @filterFiles()
-
- toggle: ->
- if @modal.showing
- @modal.hide()
- else
- @showFinder()
-
- paths: ->
- _paths = []
- for dir in File.list window.url
- continue if /\.git|Cocoa/.test dir
- if File.isDirectory dir
- _paths.push File.listDirectoryTree dir
- else
- _paths.push dir
- _.reject _.flatten(_paths), (dir) -> File.isDirectory dir
-
- showFinder: ->
- @modal.show()
- @files = []
- for file in @paths()
- @files.push file.replace "#{window.url}/", ''
- @filterFiles()
-
- findMatchingFiles: (query) ->
- return [] if not query
-
- results = []
- for file in @files
- score = file.score query
- if score > 0
- # Basename matches count for more.
- if not query.match '/'
- if name.match '/'
- score += name.replace(/^.*\//, '').score query
- else
- score *= 2
- results.push [score, file]
-
- sorted = results.sort (a, b) -> b[0] - a[0]
- _.map sorted, (el) -> el[1]
-
- filterFiles: ->
- if query = $('#filefinder input').val()
- files = @findMatchingFiles query
- else
- files = @files
- $('#filefinder ul').empty()
- for file in files[0..10]
- $('#filefinder ul').append "
#{file}"
- $('#filefinder input').focus()
- $('#filefinder li:first').addClass 'selected'
-
- openSelected: ->
- dir = window.url
- file = $('#filefinder .selected').text()
- window.open "#{dir}/#{file}"
- @toggle()
-
- moveUp: ->
- selected = $('#filefinder .selected')
- if selected.prev().length
- selected.prev().addClass 'selected'
- selected.removeClass 'selected'
-
- moveDown: ->
- selected = $('#filefinder .selected')
- if selected.next().length
- selected.next().addClass 'selected'
- selected.removeClass 'selected'
-
diff --git a/extensions/filefinder/filefinder.coffee b/extensions/filefinder/filefinder.coffee
index 69a15fc9c..3c66751a4 100644
--- a/extensions/filefinder/filefinder.coffee
+++ b/extensions/filefinder/filefinder.coffee
@@ -1,5 +1,7 @@
+_ = require 'underscore'
+
Extension = require 'extension'
-FilefinderPane = require 'filefinder/filefinder-pane'
+ModalSelector = require 'modal-selector'
module.exports =
class Filefinder extends Extension
@@ -7,8 +9,9 @@ class Filefinder extends Extension
atom.keybinder.load require.resolve "filefinder/key-bindings.coffee"
atom.on 'project:open', @startup
- startup: =>
- @pane = new FilefinderPane this
+ startup: (@project) =>
+ @pane = new ModalSelector _.map @project.urls(), (url) ->
+ name: (url.replace "#{window.url}/", ''), url: url
toggle: ->
- @pane?.toggle()
\ No newline at end of file
+ @pane?.toggle()
diff --git a/extensions/filefinder/filefinder.html b/extensions/filefinder/filefinder.html
deleted file mode 100644
index 67df1afbe..000000000
--- a/extensions/filefinder/filefinder.html
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/extensions/filefinder/stringscore.js b/extensions/filefinder/stringscore.js
deleted file mode 100644
index a734adc9f..000000000
--- a/extensions/filefinder/stringscore.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/*!
- * string_score.js: String Scoring Algorithm 0.1.9
- *
- * http://joshaven.com/string_score
- * https://github.com/joshaven/string_score
- *
- * Copyright (C) 2009-2011 Joshaven Potter
- * Copyright (C) 2010-2011 Yesudeep Mangalapilly
- * MIT license: http://www.opensource.org/licenses/mit-license.php
- *
- * Date: Tue Mar 1 2011
-*/
-
-/**
- * Scores a string against another string.
- * 'Hello World'.score('he'); //=> 0.5931818181818181
- * 'Hello World'.score('Hello'); //=> 0.7318181818181818
- */
-String.prototype.score = function(abbreviation, fuzziness) {
- var total_character_score = 0,
- abbreviation_length = abbreviation.length,
- string = this,
- string_length = string.length,
- start_of_string_bonus,
- abbreviation_score,
- fuzzies=1,
- final_score;
-
- // If the string is equal to the abbreviation, perfect match.
- if (string == abbreviation) {return 1.0;}
-
- // Walk through abbreviation and add up scores.
- for (var i = 0,
- character_score/* = 0*/,
- index_in_string/* = 0*/,
- c/* = ''*/,
- index_c_lowercase/* = 0*/,
- index_c_uppercase/* = 0*/,
- min_index/* = 0*/;
- i < abbreviation_length;
- ++i) {
-
- // Find the first case-insensitive match of a character.
- c = abbreviation[i];
-
- //index_in_string = __first_valid_index(
- // string.indexOf(c.toLowerCase()),
- // string.indexOf(c.toUpperCase())
- //);
- // Inlined the above call below.
- index_c_lowercase = string.indexOf(c.toLowerCase());
- index_c_uppercase = string.indexOf(c.toUpperCase());
- min_index = Math.min(index_c_lowercase, index_c_uppercase);
- index_in_string = (min_index > -1) ?
- min_index :
- Math.max(index_c_lowercase, index_c_uppercase);
- // End inlining.
-
- if (index_in_string === -1) {
- if (fuzziness) {
- fuzzies += 1-fuzziness;
- break;
- } else {
- return 0;
- }
- } else {
- character_score = 0.1;
- }
-
- // Set base score for matching 'c'.
-
- // Same case bonus.
- if (string[index_in_string] === c) {
- character_score += 0.1;
- }
-
- // Consecutive letter & start-of-string Bonus
- if (index_in_string === 0) {
- // Increase the score when matching first character of the
- // remainder of the string
- character_score += 0.6;
- if (i === 0) {
- // If match is the first character of the string
- // & the first character of abbreviation, add a
- // start-of-string match bonus.
- start_of_string_bonus = 1 //true;
- }
- }
-
- // Acronym Bonus
- // Weighing Logic: Typing the first character of an acronym is as if you
- // preceded it with two perfect character matches.
- if (string.charAt(index_in_string - 1) === ' ') {
- character_score += 0.8; // * Math.min(index_in_string, 5); // Cap bonus at 0.4 * 5
- }
-
- // Left trim the already matched part of the string
- // (forces sequential matching).
- string = string.substring(index_in_string + 1, string_length);
-
- total_character_score += character_score;
- } // end of for loop
-
- // Uncomment to weigh smaller words higher.
- // return total_character_score / string_length;
-
- abbreviation_score = total_character_score / abbreviation_length;
- //percentage_of_matched_string = abbreviation_length / string_length;
- //word_score = abbreviation_score * percentage_of_matched_string;
-
- // Reduce penalty for longer strings.
- //final_score = (word_score + abbreviation_score) / 2;
- final_score = ((abbreviation_score * (abbreviation_length / string_length)) + abbreviation_score) / 2;
-
- final_score = final_score / fuzzies;
-
- if (start_of_string_bonus && (final_score + 0.15 < 1)) {
- final_score += 0.15;
- }
-
- return final_score;
-};
diff --git a/src/atom/modal-selector.coffee b/src/atom/modal-selector.coffee
new file mode 100644
index 000000000..ef5a765af
--- /dev/null
+++ b/src/atom/modal-selector.coffee
@@ -0,0 +1,159 @@
+$ = require 'jquery'
+_ = require 'underscore'
+
+Modal = require 'modal'
+
+jQuery = $
+require 'stringscore'
+
+module.exports =
+class ModalSelector extends Modal
+ selectorHTML: '''
+
+ '''
+
+ showing: false
+
+ # The items to filter. An Array of {name:name, url:url} objects.
+ list: []
+
+ constructor: (@list) ->
+ super @selectorHTML
+
+ head = $('head')[0]
+ style = document.createElement 'style'
+ rules = document.createTextNode @selectorCSS
+ style.type = 'text/css'
+ style.appendChild rules
+ head.appendChild style
+
+ $('#modal-selector input').live 'keydown', @onKeydown
+
+ onKeydown: (e) =>
+ keys = up: 38, down: 40, enter: 13
+
+ if e.keyCode is keys.enter
+ @openSelected()
+ false
+ else if e.keyCode is keys.up
+ @moveUp()
+ else if e.keyCode is keys.down
+ @moveDown()
+ else
+ @filter()
+
+ show: ->
+ console.log 'cool'
+ super
+ @filter()
+
+ filter: ->
+ if query = $('#modal-selector input').val()
+ items = @findMatchingItems query
+ else
+ items = @list
+ $('#modal-selector ul').empty()
+ for {name, url} in items[0..10]
+ $('#modal-selector ul').append "#{name}"
+ $('#modal-selector input').focus()
+ $('#modal-selector li:first').addClass 'selected'
+
+ findMatchingItems: (query) ->
+ return [] if not query
+
+ results = []
+ for item in @list
+ {name, url} = item
+ score = name.score query
+ if score > 0
+ # Basename matches count for more.
+ if not query.match '/'
+ if name.match '/'
+ score += name.replace(/^.*\//, '').score query
+ else
+ score *= 2
+ results.push [score, item]
+
+ sorted = results.sort (a, b) -> b[0] - a[0]
+ _.map sorted, (el) -> el[1]
+
+ openSelected: ->
+ text = $('#modal-selector .selected').text()
+ window.open _.find(@list, (item) -> item.name is text).url
+ @toggle()
+
+ moveUp: ->
+ selected = $('#modal-selector .selected')
+ if selected.prev().length
+ selected.prev().addClass 'selected'
+ selected.removeClass 'selected'
+
+ moveDown: ->
+ selected = $('#modal-selector .selected')
+ if selected.next().length
+ selected.next().addClass 'selected'
+ selected.removeClass 'selected'
+
+ selectorCSS: '''
+#modal .content {
+ background: #ededed;
+ padding: 0;
+}
+#modal .close {
+ display: none;
+}
+#modal-selector .list {
+ height: 100px;
+ overflow: hidden;
+ padding: 10px 0;
+}
+#modal-selector input[type=search] {
+ width: 95%;
+ margin: 10px;
+}
+
+#modal .content {
+ min-width: 200px;
+ height: 100%;
+ background-color: #DDE3EA;
+ color: #000;
+ border-right: 1px solid #B4B4B4;
+ cursor: default;
+ -webkit-user-select: none;
+ overflow: auto;
+}
+
+#modal .content .cwd {
+ padding-top: 5px;
+ padding-left: 5px;
+ font-weight: bold;
+ color: #708193;
+ text-transform: uppercase;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+}
+
+#modal .content ul {
+ margin: 0;
+ padding-top: 2px;
+ list-style-type: none;
+}
+
+#modal .content li {
+ padding: 0;
+ padding-left: 5px;
+ line-height: 20px;
+ font-size: 14px;
+}
+
+#modal .content li.selected {
+ background-image: -webkit-gradient(linear,0% 0,0% 100%,from(#BCCBEB),to(#8094BB));
+ border-top: 1px solid #A0AFCD;
+ color: #fff;
+ text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5);
+}
+ '''
\ No newline at end of file