Skip to content

Instantly share code, notes, and snippets.

@melborne
Created November 7, 2010 09:26
Show Gist options
  • Save melborne/666032 to your computer and use it in GitHub Desktop.
Save melborne/666032 to your computer and use it in GitHub Desktop.
quicksilver scoring algorithm in ruby
#!/usr/local/bin/ruby
# -*- encoding:utf-8 -*-
require 'readline'
require "/Users/keyes/Dropbox/lib/ruby_class_list/rbutils"
class String
def to_score(abbrev)
return 0.9 if abbrev.empty?
return 0.0 if length < abbrev.length
tail = ""
loop do
return 0 if abbrev.empty?
unless md = match(/#{abbrev}/i)
abbrev, tail = abbrev.split_at(-1)
next
else
remaining_score = md.post_match.to_score(tail)
return calc_score(md, remaining_score)
end
end
end
protected
def calc_score(md, remaining_score)
if remaining_score.zero?
0
else
score = (1 * md.to_s.length) + (remaining_score * md.post_match.length)
if md.pre_match =~ /[\s_#:\.]+$/
score += 0.85 * (md.pre_match.length - $&.length) + 1 * $&.length
elsif !md.pre_match.empty? and md.to_s =~ /^[A-Z]/
score += 0.85 * md.pre_match.gsub(/[A-Z]/, "").length
end
score / self.length
end
end
def split_at(index)
return slice(0...index), ( slice(index..-1) || "" )
end
end
rb_classes = (RbUtils.classes + RbUtils.modules) - [RbUtils]
rb_public_methods = rb_classes.map do |klass|
meths = klass.methods_by_type
meths['public_methods'].map { |m| "#{klass}.#{m}" } +
meths['public_instance_methods'].map { |m| "#{klass}##{m}" }
end.flatten
rb_classes = (Rbutils.classes + RbUtils.modules) - [Rbutils]
WORDS = rb_public_methods
trap(:INT, "EXIT")
loop do
abbrev = Readline.readline("> ", true)
WORDS.inject([]) do |mem, app|
score = app.to_score(abbrev)
mem << [score, app] if score > 0.9
mem
end
.sort_by { |score, _| -score }
.each_with_index { |(score, app), i| printf "%2d:%s (%.4f)\n", i+1, app, score }
end
#while buf = Readline.readline("> ", true)
# exit(0) if buf =~ /exit/
#
#
#
# scores = WORDS.map{|i| [i.to_score(buf), i]}.reject{|i| i[0]<0.7}.sort
# next if scores.empty?
#
# items = scores.map{|i| i[1]}
# Readline::HISTORY.push(*items)
# if scores.last[0] == 1
# puts "open -a '#{items.last}'"
# `open -a "#{items.last}"`
# else
# scores.reverse[0, 20].each {|i| printf("%f %s\n", i[0], i[1])}
# AppleScript.key_code(126) # 竊台ク顔泙蜊ー
# end
#end
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment