mirror of
https://github.com/atom/atom.git
synced 2026-01-23 05:48:10 -05:00
Command-T: File Finder™
This commit is contained in:
79
plugins/filefinder/facebox.css
Normal file
79
plugins/filefinder/facebox.css
Normal file
@@ -0,0 +1,79 @@
|
||||
#facebox {
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
z-index:100;
|
||||
text-align:left;
|
||||
}
|
||||
|
||||
#facebox .popup{
|
||||
position:relative;
|
||||
border:3px solid rgba(0,0,0,0);
|
||||
-webkit-border-radius:5px;
|
||||
-moz-border-radius:5px;
|
||||
border-radius:5px;
|
||||
-webkit-box-shadow:0 0 18px rgba(0,0,0,0.4);
|
||||
-moz-box-shadow:0 0 18px rgba(0,0,0,0.4);
|
||||
box-shadow:0 0 18px rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
#facebox .content{
|
||||
display:table;
|
||||
width:370px;
|
||||
padding:10px;
|
||||
background:#fff;
|
||||
-webkit-border-radius:4px;
|
||||
-moz-border-radius:4px;
|
||||
border-radius:4px;
|
||||
}
|
||||
|
||||
#facebox .content > p:first-child{
|
||||
margin-top:0;
|
||||
}
|
||||
#facebox .content > p:last-child{
|
||||
margin-bottom:0;
|
||||
}
|
||||
|
||||
#facebox .close{
|
||||
position:absolute;
|
||||
top:5px;
|
||||
right:5px;
|
||||
padding:2px;
|
||||
width:8px;
|
||||
height:8px;
|
||||
opacity:0.3;
|
||||
z-index:10000;
|
||||
}
|
||||
#facebox .close:hover{
|
||||
opacity:1.0;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
#facebox .fb-loading{
|
||||
height:32px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
#facebox img{
|
||||
display:block;
|
||||
border:0;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
#facebox-overlay{
|
||||
position:fixed;
|
||||
top:0px;
|
||||
left:0px;
|
||||
height:100%;
|
||||
width:100%;
|
||||
background-color:#000;
|
||||
z-index:99;
|
||||
display:none;
|
||||
}
|
||||
|
||||
#facebox .close.inline{
|
||||
background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEpJREFUeNpiYGBgEAXivUCsxYAAukC8CyoHlvwPxK+gErpQ9n+oHIrAKzS2LrKRMAkUSSYG3OAvNt1YrSDoSJg3ddG8CRITBQgwALGIIG7dYZgsAAAAAElFTkSuQmCC") top right no-repeat;
|
||||
}
|
||||
#facebox .fb-loading{
|
||||
background:center url("data:image/gif;base64,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") no-repeat;
|
||||
}
|
||||
154
plugins/filefinder/facebox.js
Normal file
154
plugins/filefinder/facebox.js
Normal file
@@ -0,0 +1,154 @@
|
||||
// facebox 2.0
|
||||
// MIT Licensed
|
||||
// https://github.com/defunkt/facebox
|
||||
(function($){
|
||||
|
||||
// jQuery plugin
|
||||
//
|
||||
// $('a[rel*=facebox]').facebox()
|
||||
// $('.js-add-cc').facebox(function() {
|
||||
// $('#facebox .js-thanks, #facebox .rule:first').hide()
|
||||
// })
|
||||
$.fn.facebox = function( callback ) {
|
||||
return this.live('click.facebox', function(){
|
||||
// rel="facebox.my-class" adds my-class to '#facebox .content'
|
||||
var contentClass = ( /facebox\.(\S+)/.exec(this.rel) || [] )[1]
|
||||
|
||||
if ( callback )
|
||||
$(document).one('show.facebox', callback)
|
||||
|
||||
$.facebox({ div: this.href }, contentClass)
|
||||
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
// The Real Deal
|
||||
//
|
||||
// $.facebox('<b>Cool!</b>')
|
||||
$.facebox = function( data, contentClass ) {
|
||||
if ( $('#facebox .fb-loading').length == 0 ) {
|
||||
show('<div class="fb-loading"> </div>')
|
||||
$(document).trigger('loading.facebox')
|
||||
}
|
||||
|
||||
$('#facebox .content').addClass(contentClass)
|
||||
|
||||
if ( !data ) return
|
||||
|
||||
// $.facebox('#info') => $.facebox({div: '#info'})
|
||||
if ( /^#/.test(data) )
|
||||
data = { div: data }
|
||||
|
||||
// $.facebox('/some/url') => $.facebox({ajax: '/some/url' })
|
||||
if ( /^\//.test(data) )
|
||||
data = { ajax: data }
|
||||
|
||||
var href = data.ajax || data.image || data.div
|
||||
if ( href ) {
|
||||
// div
|
||||
var div = /#.+$/.exec(href)
|
||||
if ( div ) {
|
||||
show( $(div[0]).html() )
|
||||
|
||||
// image
|
||||
} else if ( data.image || /\.(png|jpe?g|gif)(\?\S*)?$/i.test(href) ) {
|
||||
var image = new Image
|
||||
image.onload = function() {
|
||||
show('<img src="' + image.src + '" />')
|
||||
}
|
||||
image.src = href
|
||||
|
||||
// ajax
|
||||
} else {
|
||||
$.get(href, show)
|
||||
}
|
||||
}
|
||||
|
||||
else if ( $.isFunction(data) )
|
||||
data()
|
||||
else
|
||||
show(data)
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Default settings
|
||||
//
|
||||
|
||||
var settings = $.facebox.settings = {
|
||||
opacity : 0.2,
|
||||
overlay : true,
|
||||
faceboxHTML: '<div id="facebox"><div class="popup"><div class="content"></div><a href="#" class="close inline"> </a></div></div>'
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
|
||||
// Close Facebox
|
||||
var close = $.facebox.close = function(){
|
||||
$(document).trigger('close.facebox')
|
||||
return false
|
||||
}
|
||||
|
||||
// Show the Facebox
|
||||
function show( data ) {
|
||||
// Dim the lights
|
||||
if ( settings.overlay && !$('#facebox-overlay').is(':visible') ) {
|
||||
$('body').append('<div id="facebox-overlay"></div>')
|
||||
|
||||
$('#facebox-overlay')
|
||||
.css('opacity', settings.opacity)
|
||||
.fadeIn(200)
|
||||
.click(close)
|
||||
}
|
||||
|
||||
// Create the Facebox
|
||||
if ( $('#facebox').length == 0 ) {
|
||||
$('body').append( $(settings.faceboxHTML).hide() )
|
||||
$(document).trigger('setup.facebox')
|
||||
}
|
||||
|
||||
// Make that money
|
||||
$('#facebox .content').html(data).show()
|
||||
|
||||
// Position Facebox based on the user's scroll
|
||||
$('#facebox').show().css({
|
||||
top: $(window).scrollTop() + ($(window).height() / 10),
|
||||
left: $(window).width() / 2 - ($('#facebox .popup').outerWidth() / 2)
|
||||
})
|
||||
|
||||
// Fire events if we're not loading.
|
||||
if ( $('.fb-loading:visible').length == 0 )
|
||||
$(document).trigger('show.facebox').trigger('reveal.facebox')
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Bindings
|
||||
//
|
||||
|
||||
$(document).bind('close.facebox', function(){
|
||||
$('#facebox').fadeOut(function(){
|
||||
$(this).remove()
|
||||
$(document).trigger('afterClose.facebox')
|
||||
})
|
||||
|
||||
$('#facebox-overlay').fadeOut(200, function(){
|
||||
$(this).remove()
|
||||
})
|
||||
})
|
||||
|
||||
$(document).one('show.facebox', function(){
|
||||
// Click on close image = Close Facebox
|
||||
$('#facebox .close').live('click', close)
|
||||
|
||||
// ESC = Close Facebox
|
||||
$(document).bind('keydown.facebox', function(e){
|
||||
if ( e.keyCode == 27 && $('#facebox:visible').length ) close()
|
||||
return true
|
||||
})
|
||||
})
|
||||
})(jQuery);
|
||||
106
plugins/filefinder/filefinder.coffee
Normal file
106
plugins/filefinder/filefinder.coffee
Normal file
@@ -0,0 +1,106 @@
|
||||
$ = require 'jquery'
|
||||
_ = require 'underscore'
|
||||
|
||||
{activeWindow} = require 'app'
|
||||
File = require 'fs'
|
||||
Pane = require 'pane'
|
||||
|
||||
jQuery = $
|
||||
facebox = eval File.read require.resolve 'filefinder/facebox'
|
||||
require 'filefinder/stringscore'
|
||||
|
||||
module.exports =
|
||||
class Filefinder extends Pane
|
||||
showing: false
|
||||
files: []
|
||||
|
||||
html: require "filefinder/filefinder.html"
|
||||
|
||||
keymap:
|
||||
'Command-T': 'toggle'
|
||||
# really wish i could put up/down keyboad shortcuts here
|
||||
# and have them activated when the filefinder is open
|
||||
|
||||
initialize: ->
|
||||
$('#filefinder input').live 'keydown', @onKeydown
|
||||
|
||||
css = File.read require.resolve 'filefinder/facebox.css'
|
||||
head = $('head')[0]
|
||||
style = document.createElement 'style'
|
||||
rules = document.createTextNode css
|
||||
style.type = 'text/css'
|
||||
style.appendChild rules
|
||||
head.appendChild style
|
||||
|
||||
onKeydown: (e) =>
|
||||
keys = up: 38, down: 40, enter: 13
|
||||
|
||||
if e.keyCode is keys.enter
|
||||
@openSelected()
|
||||
else if e.keyCode is keys.up
|
||||
@moveUp()
|
||||
else if e.keyCode is keys.down
|
||||
@moveDown()
|
||||
else
|
||||
@filterFiles()
|
||||
|
||||
toggle: ->
|
||||
if @showing
|
||||
$.facebox.close()
|
||||
else
|
||||
@showFinder()
|
||||
@showing = not @showing
|
||||
|
||||
showFinder: ->
|
||||
$.facebox @html
|
||||
@files = []
|
||||
for file in activeWindow.project.paths()
|
||||
@files.push file.replace "#{activeWindow.project.dir}/", ''
|
||||
@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 "<li>#{file}</li>"
|
||||
$('#filefinder input').focus()
|
||||
$('#filefinder li:first').addClass 'selected'
|
||||
|
||||
openSelected: ->
|
||||
dir = activeWindow.project.dir
|
||||
file = $('#filefinder .selected').text()
|
||||
activeWindow.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'
|
||||
17
plugins/filefinder/filefinder.html
Normal file
17
plugins/filefinder/filefinder.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<style>
|
||||
#filefinder .filelist {
|
||||
height: 100px;
|
||||
overflow: hidden;
|
||||
padding: 10px 0;
|
||||
}
|
||||
#filefinder .filelist .selected {
|
||||
background-color: yellow;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id='filefinder'>
|
||||
<input type='search'>
|
||||
<br>
|
||||
<ul class='filelist'>
|
||||
</ul>
|
||||
</div>
|
||||
3
plugins/filefinder/index.coffee
Normal file
3
plugins/filefinder/index.coffee
Normal file
@@ -0,0 +1,3 @@
|
||||
exports.Filefinder = Filefinder = require 'filefinder/filefinder'
|
||||
|
||||
new Filefinder
|
||||
122
plugins/filefinder/stringscore.js
Normal file
122
plugins/filefinder/stringscore.js
Normal file
@@ -0,0 +1,122 @@
|
||||
/*!
|
||||
* 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 <yourtech@gmail.com>
|
||||
* Copyright (C) 2010-2011 Yesudeep Mangalapilly <yesudeep@gmail.com>
|
||||
* 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;
|
||||
};
|
||||
Reference in New Issue
Block a user