mirror of
https://github.com/kennethreitz-archive/kJS.tmbundle.git
synced 2026-06-05 23:50:19 +00:00
Moved complete inside the bundle for those without the latest review support
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<string>nop</string>
|
||||
<key>command</key>
|
||||
<string>#!/usr/bin/env ruby
|
||||
require ENV['TM_SUPPORT_PATH'] + '/lib/tm/complete'
|
||||
require ENV['TM_BUNDLE_SUPPORT'] + '/lib/tm/complete'
|
||||
TextMate::Complete.new.complete!
|
||||
</string>
|
||||
<key>input</key>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<string>nop</string>
|
||||
<key>command</key>
|
||||
<string>#!/usr/bin/env ruby
|
||||
require ENV['TM_SUPPORT_PATH'] + '/lib/tm/complete'
|
||||
require ENV['TM_BUNDLE_SUPPORT'] + '/lib/tm/complete'
|
||||
TextMate::Complete.new.tip!
|
||||
</string>
|
||||
<key>fallbackInput</key>
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
# When creating a custom regex for Word.current_word, you need to keep a few things in mind:
|
||||
# The regex matches from your caret, so your caret position will always be the beginning of the line
|
||||
# Everything before your caret is reversed for the match, so the left of your caret will also match your caret position as ^
|
||||
# You must use a capture group () for the text you're trying to match
|
||||
# You must use a capture group () for the text before/after your match
|
||||
#
|
||||
# EG: /(^[a-z]*)(.*$)/
|
||||
# The first capture group in that regex will match from your caret out until it can't find anymore lowercase letters.
|
||||
# Then it'll match everything else in the line as the before/after match part.
|
||||
# You can currently only use a single regex to match before and after your caret.
|
||||
#
|
||||
# Since your regex matches what's before your caret in reverse, you'll have to reverse specific stuff in your regex, eg:
|
||||
# /(.*):/ wouldn't match 'color' in ` color: `, but /:(.*)/ would.
|
||||
# It's reversed you see
|
||||
#
|
||||
module Word
|
||||
def self.current_word(pat='a-zA-Z0-9', direction=:both)
|
||||
word = ENV['TM_SELECTED_TEXT']
|
||||
|
||||
if word.nil? or word.empty?
|
||||
line, col = ENV['TM_CURRENT_LINE'], ENV['TM_LINE_INDEX'].to_i
|
||||
|
||||
if pat.kind_of? Regexp
|
||||
@reg = pat
|
||||
else
|
||||
@reg = /(^[#{pat}]*)(.*$\r?\n?)/
|
||||
end
|
||||
|
||||
left, before_match = *( line[0...col].reverse.match(@reg) ||[])[1..2]
|
||||
right, after_match = *( line[col..-1] .match(@reg) ||[])[1..2]
|
||||
|
||||
(before_match||='').reverse!
|
||||
(left||='').reverse!
|
||||
|
||||
# p before_match, left, right, after_match
|
||||
|
||||
case direction
|
||||
when :both then word = [left, right].join('')
|
||||
when :left then word = left
|
||||
when :right then word = right
|
||||
when :hash then word = {
|
||||
:line => [before_match, left, right, after_match].join(''),
|
||||
:before_match => before_match,
|
||||
:left => left,
|
||||
:right => right,
|
||||
:after_match => after_match,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
word
|
||||
end
|
||||
end
|
||||
|
||||
if __FILE__ == $0
|
||||
require "test/unit"
|
||||
class TestWord < Test::Unit::TestCase
|
||||
# =begin
|
||||
def test_with_spaces
|
||||
ENV['TM_SELECTED_TEXT']= nil
|
||||
ENV['TM_CURRENT_LINE'] = <<-EOF
|
||||
BeforeAfter
|
||||
EOF
|
||||
ENV['TM_LINE_INDEX'] = '10'
|
||||
ENV['TM_TAB_SIZE'] = '2'
|
||||
assert_equal 'BeforeAfter', Word.current_word
|
||||
assert_equal 'Before', Word.current_word('a-zA-Z0-9',:left)
|
||||
assert_equal 'After', Word.current_word('a-zA-Z0-9',:right)
|
||||
|
||||
assert_equal ' Before', Word.current_word(" a-zA-Z",:left)
|
||||
assert_equal 'After ', Word.current_word(" a-zA-Z",:right)
|
||||
end
|
||||
|
||||
def test_with_tabs
|
||||
ENV['TM_SELECTED_TEXT']= nil
|
||||
ENV['TM_CURRENT_LINE'] = <<-EOF
|
||||
BeforeAfter
|
||||
EOF
|
||||
ENV['TM_LINE_INDEX'] = '8'
|
||||
ENV['TM_TAB_SIZE'] = '2'
|
||||
assert_equal 'BeforeAfter', Word.current_word
|
||||
assert_equal 'Before', Word.current_word('a-zA-Z0-9',:left)
|
||||
assert_equal 'After', Word.current_word('a-zA-Z0-9',:right)
|
||||
|
||||
assert_equal "\t\tBefore", Word.current_word("\ta-zA-Z",:left)
|
||||
assert_equal "After\t\t", Word.current_word("\ta-zA-Z",:right)
|
||||
end
|
||||
|
||||
def test_with_dash
|
||||
ENV['TM_SELECTED_TEXT']= nil
|
||||
ENV['TM_CURRENT_LINE'] = <<-EOF
|
||||
Before--After
|
||||
EOF
|
||||
ENV['TM_LINE_INDEX'] = '11'
|
||||
ENV['TM_TAB_SIZE'] = '2'
|
||||
assert_equal 'Before--After', Word.current_word('-a-zA-Z0-9')
|
||||
assert_equal 'Before-', Word.current_word('-a-zA-Z0-9',:left)
|
||||
assert_equal '-After', Word.current_word('-a-zA-Z0-9',:right)
|
||||
|
||||
assert_equal 'Before-', Word.current_word("\ta-zA-Z\-",:left)
|
||||
end
|
||||
|
||||
def test_hash_result
|
||||
ENV['TM_SELECTED_TEXT']= nil
|
||||
ENV['TM_CURRENT_LINE'] = <<-EOF
|
||||
before_match BeforeAfter after_match
|
||||
EOF
|
||||
ENV['TM_LINE_INDEX'] = '22'
|
||||
ENV['TM_TAB_SIZE'] = '2'
|
||||
|
||||
word = Word.current_word("a-zA-Z",:hash)
|
||||
|
||||
assert_equal ENV['TM_CURRENT_LINE'], "#{word[:line]}"
|
||||
assert_equal 'Before', word[:left]
|
||||
assert_equal 'After', word[:right]
|
||||
end
|
||||
=begin
|
||||
=end
|
||||
def test_both_result
|
||||
ENV['TM_SELECTED_TEXT']= nil
|
||||
ENV['TM_CURRENT_LINE'] = <<-EOF
|
||||
before_match BeforeAfter after_match
|
||||
EOF
|
||||
ENV['TM_LINE_INDEX'] = '22'
|
||||
ENV['TM_TAB_SIZE'] = '2'
|
||||
|
||||
assert_equal 'BeforeAfter', Word.current_word("a-zA-Z",:both)
|
||||
end
|
||||
|
||||
def test_should_support_custom_regex
|
||||
ENV['TM_SELECTED_TEXT']= nil
|
||||
ENV['TM_CURRENT_LINE'] = <<-EOF
|
||||
before_match BeforeAfter after_match
|
||||
EOF
|
||||
ENV['TM_LINE_INDEX'] = '22'
|
||||
ENV['TM_TAB_SIZE'] = '2'
|
||||
|
||||
assert_equal '', Word.current_word(/[a-zA-Z]/,:both) # No match since no capture group was used!
|
||||
|
||||
assert_equal 'ef', Word.current_word(/([a-z])/,:both) # Capture group, but only selecting a single caracter before and after the caret
|
||||
assert_equal 'eforefter', Word.current_word(/([a-z]+)/,:both) # Only lowercase characters
|
||||
assert_equal 'BeforeAfter', Word.current_word(/^([a-z]*)/i,:both) # Ignore case
|
||||
assert_equal 'BeforeAfter', Word.current_word(/^([a-zA-Z]*)/,:both) # Explicit case
|
||||
end
|
||||
|
||||
def test_should_support_custom_regex_example1
|
||||
ENV['TM_SELECTED_TEXT']= nil
|
||||
ENV['TM_CURRENT_LINE'] = <<-EOF
|
||||
background-color: ;
|
||||
EOF
|
||||
ENV['TM_LINE_INDEX'] = '20'
|
||||
ENV['TM_TAB_SIZE'] = '2'
|
||||
|
||||
assert_equal ' background-color: ', Word.current_word(/^(.*)/,:left)
|
||||
assert_equal 'background-color', Word.current_word(/:([-a-z]+)/,:left)
|
||||
end
|
||||
|
||||
def test_should_support_custom_regex_example2
|
||||
ENV['TM_SELECTED_TEXT']= nil
|
||||
ENV['TM_CURRENT_LINE'] = <<-EOF
|
||||
<p class="className" id="flarm">Lorem ipsum dolor sit amet</p>
|
||||
EOF
|
||||
ENV['TM_LINE_INDEX'] = '44'
|
||||
ENV['TM_TAB_SIZE'] = '2'
|
||||
|
||||
assert_equal %Q{\t<p class="className" id="flarm">Lorem ipsum}, Word.current_word(/^(.*)/,:left)
|
||||
assert_equal 'Lorem ipsum dolor sit amet', Word.current_word(/^([^<>]+)/i,:both)
|
||||
|
||||
# You have to reverse the regex since it's matching against the reverse of the text before the caret
|
||||
assert_equal 'p', Word.current_word(/([-:a-z]+)</,:left)
|
||||
# You don't have to reverse your regex when matching text after the caret
|
||||
assert_equal 'p', Word.current_word(/<\/([-:a-z]+)/,:right)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,501 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + "/../current_word"
|
||||
require ENV['TM_SUPPORT_PATH'] + '/lib/ui'
|
||||
require ENV['TM_SUPPORT_PATH'] + '/lib/escape'
|
||||
require ENV['TM_SUPPORT_PATH'] + '/lib/osx/plist'
|
||||
require 'rubygems'
|
||||
require 'json'
|
||||
require 'shellwords'
|
||||
|
||||
module TextMate
|
||||
class Complete
|
||||
IMAGES_FOLDER_NAME = 'icons'
|
||||
IMAGES = {
|
||||
"C" => "/Applications/TextMate.app/Contents/Resources/Bundle Item Icons/Commands.png",
|
||||
"D" => "/Applications/TextMate.app/Contents/Resources/Bundle Item Icons/Drag Commands.png",
|
||||
"L" => "/Applications/TextMate.app/Contents/Resources/Bundle Item Icons/Languages.png",
|
||||
"M" => "/Applications/TextMate.app/Contents/Resources/Bundle Item Icons/Macros.png",
|
||||
"P" => "/Applications/TextMate.app/Contents/Resources/Bundle Item Icons/Preferences.png",
|
||||
"S" => "/Applications/TextMate.app/Contents/Resources/Bundle Item Icons/Snippets.png",
|
||||
"T" => "/Applications/TextMate.app/Contents/Resources/Bundle Item Icons/Templates.png",
|
||||
"Doc" => "/Applications/TextMate.app/Contents/Resources/Bundle Item Icons/Template Files.png",
|
||||
}
|
||||
|
||||
def initialize
|
||||
end
|
||||
|
||||
# 0-config completion command using environment variables for everything
|
||||
def complete!
|
||||
return choices unless choices
|
||||
TextMate::UI.complete(choices, {:images => images, :extra_chars => extra_chars})
|
||||
end
|
||||
|
||||
def tip!
|
||||
# If there is no current_word, then check the next current_word
|
||||
# If there really is no current_word, then show a menu of choices
|
||||
|
||||
chars = "a-zA-Z0-9" # Hard-coded into D2
|
||||
chars += Regexp.escape(extra_chars) if extra_chars
|
||||
current_word ||= Word.current_word chars, :both
|
||||
|
||||
result = nil
|
||||
menu_choices = nil
|
||||
choices = nil
|
||||
choice = 0
|
||||
|
||||
[current_word, current_method_name, current_collection_name].each do |initial_filter|
|
||||
next unless initial_filter and not initial_filter.empty?
|
||||
# p initial_filter
|
||||
|
||||
choices = self.choices.select { |c| (c['match'] || c['display']) =~ /^#{Regexp.quote(initial_filter)}/ }
|
||||
|
||||
# p choices
|
||||
break if choices and not choices.empty?
|
||||
end
|
||||
choices ||= self.choices
|
||||
|
||||
menu_choices = choices.map { |c| c['display'] }
|
||||
choice = TextMate::UI.menu(menu_choices) if menu_choices and menu_choices.length > 1
|
||||
if choice
|
||||
result = choices[choice]
|
||||
end
|
||||
|
||||
TextMate::UI.tool_tip( result['tool_tip'], {:format => result['tool_tip_format'] || :text }) if result
|
||||
end
|
||||
|
||||
def choices
|
||||
@choices ||= data['suggestions']
|
||||
end
|
||||
def choices= choice_array
|
||||
@choices = array_to_suggestions(choice_array)
|
||||
end
|
||||
|
||||
def images
|
||||
@images = data['images'] || IMAGES
|
||||
|
||||
data['images']||{}.each_pair do |name,path|
|
||||
@images[name] = path
|
||||
next if File.exists? @images[name]
|
||||
@images[name] = ENV['TM_BUNDLE_SUPPORT'] + "/#{IMAGES_FOLDER_NAME}/" + path
|
||||
next if File.exists? @images[name]
|
||||
@images[name] = ENV['TM_SUPPORT_PATH'] + "/#{IMAGES_FOLDER_NAME}/" + path
|
||||
next if File.exists? @images[name]
|
||||
end
|
||||
|
||||
@images
|
||||
end
|
||||
|
||||
def tool_tip_prefix
|
||||
@tool_tip_prefix ||= data['tool_tip_prefix']
|
||||
end
|
||||
|
||||
def extra_chars
|
||||
ENV['TM_COMPLETIONS_EXTRACHARS'] || data['extra_chars']
|
||||
end
|
||||
|
||||
def chars
|
||||
"a-zA-Z0-9"
|
||||
end
|
||||
|
||||
private
|
||||
def data(raw_data=nil)
|
||||
fix_legacy
|
||||
|
||||
raw_data ||= read_data
|
||||
return {} unless raw_data and not raw_data.empty?
|
||||
|
||||
@data = parse_data raw_data
|
||||
return @data
|
||||
end
|
||||
|
||||
def read_data
|
||||
raw_data = read_file
|
||||
raw_data ||= read_string
|
||||
raw_data
|
||||
end
|
||||
|
||||
def read_file
|
||||
paths = [ENV['TM_COMPLETIONS_FILE']] if ENV['TM_COMPLETIONS_FILE']
|
||||
paths ||= Shellwords.shellwords( ENV['TM_COMPLETIONS_FILES'] ) if ENV.has_key?('TM_COMPLETIONS_FILES')
|
||||
return nil unless paths
|
||||
|
||||
paths.map do |path|
|
||||
next unless path and not path.empty?
|
||||
path = ENV['TM_BUNDLE_SUPPORT'] + '/' + path unless File.exists? path
|
||||
next unless File.exists? path
|
||||
|
||||
{ :data => File.read(path),
|
||||
:format => path.scan(/\.([^\.]+)$/).last.last
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def read_string
|
||||
[{:data => ENV['TM_COMPLETIONS'],
|
||||
:format => ENV['TM_COMPLETIONS_SPLIT']
|
||||
}]
|
||||
end
|
||||
|
||||
attr_accessor :filepath
|
||||
|
||||
def parse_data(raw_datas)
|
||||
return @parsed if @parsed
|
||||
parsed = {"suggestions"=>[]}
|
||||
|
||||
raw_datas.each do |raw_data|
|
||||
suggestions = parsed['suggestions']
|
||||
|
||||
case raw_data[:format]
|
||||
when 'plist'
|
||||
par = parse_plist(raw_data)
|
||||
when 'json'
|
||||
par = parse_json(raw_data)
|
||||
when "txt"
|
||||
raw_data[:format] = "\n"
|
||||
par = parse_string(raw_data)
|
||||
when nil
|
||||
raw_data[:format] = ","
|
||||
par = parse_string(raw_data)
|
||||
else
|
||||
par = parse_string(raw_data)
|
||||
end
|
||||
|
||||
if par['tool_tip_prefix']
|
||||
par['suggestions'] = par['suggestions'].map do |suggestion|
|
||||
suggestion['tool_tip'] = par['tool_tip_prefix'] + suggestion['tool_tip']
|
||||
suggestion
|
||||
end
|
||||
end
|
||||
|
||||
parsed.merge! par
|
||||
parsed['suggestions'] = suggestions + parsed['suggestions']
|
||||
end
|
||||
|
||||
@parsed = parsed
|
||||
end
|
||||
def parse_string(raw_data)
|
||||
return {} unless raw_data and raw_data[:data]
|
||||
return raw_data[:data] unless raw_data[:data].respond_to? :to_str
|
||||
raw_data[:data] = raw_data[:data].to_str
|
||||
|
||||
data = {}
|
||||
data['suggestions'] = array_to_suggestions(raw_data[:data].split(raw_data[:format]))
|
||||
data
|
||||
end
|
||||
def parse_plist(raw_data)
|
||||
OSX::PropertyList.load(raw_data[:data])
|
||||
end
|
||||
def parse_json(raw_data)
|
||||
JSON.parse(raw_data[:data])
|
||||
end
|
||||
|
||||
def array_to_suggestions(suggestions)
|
||||
suggestions.delete('')
|
||||
|
||||
suggestions.map! do |c|
|
||||
{'display' => c}
|
||||
end
|
||||
|
||||
suggestions
|
||||
end
|
||||
def current_method_name
|
||||
# Regex for finding a method or function name that's close to your caret position using Word.current_word
|
||||
# TODO: Allow completion prefs to define their own Complete.tip! method_name
|
||||
|
||||
characters = "a-zA-Z0-9" # Hard-coded into D2
|
||||
characters += Regexp.escape(extra_chars) if extra_chars
|
||||
|
||||
regex = %r/
|
||||
(?> [^\(\)]+ | \) (?> [^\(\)]+ | \) (?> [^\(\)]+ | \) (?> [^\(\)]+ | \) (?> [^\(\)]+ | \) (?> [^\(\)]* ) \( | )+ \( | )+ \( | )+ \( | )+ \( | )+
|
||||
(?: \(([#{characters}]+) )?/ix
|
||||
|
||||
Word.current_word(regex,:left)
|
||||
end
|
||||
def current_collection_name
|
||||
characters = "a-zA-Z0-9" # Hard-coded into D2
|
||||
characters += Regexp.escape(extra_chars) if extra_chars
|
||||
|
||||
regex = %r/
|
||||
(?> [^\[\]]+ | \] (?> [^\[\]]+ | \] (?> [^\[\]]+ | \] (?> [^\[\]]+ | \] (?> [^\[\]]+ | \] (?> [^\[\]]* ) \[ | )+ \[ | )+ \[ | )+ \[ | )+ \[ | )+
|
||||
(?: \[([#{characters}]+) )?/ix
|
||||
|
||||
Word.current_word(regex,:left)
|
||||
end
|
||||
|
||||
def fix_legacy
|
||||
ENV['TM_COMPLETIONS_SPLIT'] ||= ENV['TM_COMPLETIONS_split']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if __FILE__ == $0
|
||||
|
||||
`open "txmt://open?url=file://$TM_FILEPATH"` #For testing purposes, make this document the topmost so that the complete popup works
|
||||
ENV['WEB_PREVIEW_RUBY']='NO-RUN'
|
||||
require "test/unit"
|
||||
# require "complete"
|
||||
|
||||
class TestComplete < Test::Unit::TestCase
|
||||
def setup
|
||||
@string_raw = 'ad(),adipisicing,aliqua,aliquip,amet,anim,aute,cillum,commodo,consectetur,consequat,culpa,cupidatat,deserunt,do,dolor,dolore,Duis,ea,eiusmod,elit,enim,esse,est,et,eu,ex,Excepteur,exercitation,fugiat,id,in,incididunt,ipsum,irure,labore,laboris,laborum,Lorem,magna,minim,mollit,nisi,non,nostrud,nulla,occaecat,officia,pariatur,proident,qui,quis,reprehenderit,sed,sint,sit,sunt,tempor,ullamco,Ut,ut,velit,veniam,voluptate,'
|
||||
|
||||
@plist_raw = <<-'PLIST'
|
||||
{ suggestions = (
|
||||
{ display = moo; image = Drag; insert = "(${1:one}, ${2:one}, ${3:three}${4:, ${5:five}, ${6:six}})"; tool_tip = "moo(one, two, four[, five])\n This method does something or other maybe.\n Insert longer description of it here."; },
|
||||
{ display = foo; image = Macro; insert = "(${1:one}, \"${2:one}\", ${3:three}${4:, ${5:five}, ${6:six}})"; tool_tip = "foo(one, two)\n This method does something or other maybe.\n Insert longer description of it here."; },
|
||||
{ display = bar; image = Command; insert = "(${1:one}, ${2:one}, \"${3:three}\"${4:, \"${5:five}\", ${6:six}})"; tool_tip = "bar(one, two[, three])\n This method does something or other maybe.\n Insert longer description of it here."; }
|
||||
);
|
||||
extra_chars = '.';
|
||||
images = {
|
||||
Command = "Commands.png";
|
||||
Drag = "Drag Commands.png";
|
||||
Language = "Languages.png";
|
||||
Macro = "Macros.png";
|
||||
Preference = "Preferences.png";
|
||||
Snippet = "Snippets.png";
|
||||
Template = "Template Files.png";
|
||||
Templates = "Templates.png";
|
||||
};
|
||||
}
|
||||
PLIST
|
||||
|
||||
@json_raw = <<-'JSON'
|
||||
{
|
||||
"extra_chars": "-_$.",
|
||||
"suggestions": [
|
||||
{ "display": ".moo", "image": "", "insert": "(${1:one}, ${2:one}, ${3:three}${4:, ${5:five}, ${6:six}})", "tool_tip": "moo(one, two, four[, five])\n This method does something or other maybe.\n Insert longer description of it here." },
|
||||
{ "display": "foo", "image": "", "insert": "(${1:one}, \"${2:one}\", ${3:three}${4:, ${5:five}, ${6:six}})", "tool_tip": "foo(one, two)\n This method does something or other maybe.\n Insert longer description of it here." },
|
||||
{ "display": "bar", "image": "", "insert": "(${1:one}, ${2:one}, \"${3:three}\"${4:, \"${5:five}\", ${6:six}})", "tool_tip": "bar(one, two[, three])\n This method does something or other maybe.\n Insert longer description of it here." }
|
||||
],
|
||||
"images": {
|
||||
"String" : "String.png",
|
||||
"RegExp" : "RegExp.png",
|
||||
"Number" : "Number.png",
|
||||
"Array" : "Array.png",
|
||||
"Function": "Function.png",
|
||||
"Object" : "Object.png",
|
||||
"Node" : "Node.png",
|
||||
"NodeList": "NodeList.png"
|
||||
}
|
||||
}
|
||||
JSON
|
||||
end
|
||||
|
||||
def test_basic_complete
|
||||
ENV['TM_COMPLETIONS'] = @string_raw
|
||||
|
||||
assert_equal ENV['TM_COMPLETIONS'].split(','), TextMate::Complete.new.choices.map{|c| c['display']}
|
||||
assert_equal TextMate::Complete::IMAGES, TextMate::Complete.new.images
|
||||
|
||||
TextMate::Complete.new.complete!
|
||||
end
|
||||
#
|
||||
def test_should_support_plist
|
||||
ENV['TM_COMPLETIONS_SPLIT']='plist'
|
||||
ENV['TM_COMPLETIONS'] = @plist_raw
|
||||
TextMate::Complete.new.complete!
|
||||
end
|
||||
#
|
||||
def test_should_support_json
|
||||
ENV.delete 'TM_COMPLETIONS'
|
||||
assert_nil(ENV['TM_COMPLETIONS'])
|
||||
ENV.delete 'TM_COMPLETIONS_SPLIT'
|
||||
assert_nil(ENV['TM_COMPLETIONS_SPLIT'])
|
||||
|
||||
ENV['TM_COMPLETIONS_SPLIT']='json'
|
||||
ENV['TM_COMPLETIONS'] = @json_raw
|
||||
fred = TextMate::Complete.new
|
||||
assert_equal(3, fred.choices.length)
|
||||
end
|
||||
#
|
||||
def test_should_be_able_to_modify_the_choices
|
||||
ENV['TM_COMPLETIONS'] = @string_raw
|
||||
|
||||
fred = TextMate::Complete.new
|
||||
|
||||
assert_not_nil fred.choices
|
||||
assert_equal ENV['TM_COMPLETIONS'].split(','), fred.choices.map{|c| c['display']}
|
||||
fred.choices.reject!{|choice| choice['display'] !~ /^a/ }
|
||||
assert_equal ENV['TM_COMPLETIONS'].split(',').grep(/^a/), fred.choices.map{|c| c['display']}
|
||||
|
||||
fred.choices=%w[fred is not my name]
|
||||
assert_equal %w[fred is not my name], fred.choices.map{|c| c['display']}
|
||||
end
|
||||
#
|
||||
def test_should_parse_files_based_on_extension_plist
|
||||
ENV['TM_COMPLETIONS_FILE'] = '/tmp/completions_test.plist'
|
||||
|
||||
File.open(ENV['TM_COMPLETIONS_FILE'],'w'){|file| file.write @plist_raw }
|
||||
assert File.exists?(ENV['TM_COMPLETIONS_FILE'])
|
||||
|
||||
fred = TextMate::Complete.new
|
||||
assert_equal(['moo', 'foo', 'bar'], fred.choices.map{|c| c['display']})
|
||||
end
|
||||
#
|
||||
def test_should_parse_files_based_on_extension_txt
|
||||
ENV.delete 'TM_COMPLETIONS'
|
||||
assert_nil(ENV['TM_COMPLETIONS'])
|
||||
ENV.delete 'TM_COMPLETIONS_SPLIT'
|
||||
assert_nil(ENV['TM_COMPLETIONS_SPLIT'])
|
||||
|
||||
ENV['TM_COMPLETIONS_FILE'] = '/tmp/completions_test.txt'
|
||||
|
||||
File.open(ENV['TM_COMPLETIONS_FILE'],'w'){|file| file.write @string_raw.gsub(',',"\n") }
|
||||
assert File.exists?(ENV['TM_COMPLETIONS_FILE'])
|
||||
|
||||
fred = TextMate::Complete.new
|
||||
|
||||
assert_equal(@string_raw.split(','), fred.choices.map{|c| c['display']})
|
||||
end
|
||||
#
|
||||
def test_should_parse_multiple_files
|
||||
ENV.delete 'TM_COMPLETIONS'
|
||||
assert_nil(ENV['TM_COMPLETIONS'])
|
||||
ENV.delete 'TM_COMPLETIONS_SPLIT'
|
||||
assert_nil(ENV['TM_COMPLETIONS_SPLIT'])
|
||||
ENV.delete 'TM_COMPLETIONS_FILE'
|
||||
assert_nil(ENV['TM_COMPLETIONS_FILE'])
|
||||
|
||||
ENV['TM_COMPLETIONS_FILES'] = "'/tmp/completions_test.txt' '/tmp/completions_test1.txt' '/tmp/completions_test2.txt'"
|
||||
|
||||
require 'shellwords'
|
||||
Shellwords.shellwords( ENV['TM_COMPLETIONS_FILES'] ).each_with_index do |filepath,i|
|
||||
File.open(filepath,'w'){|file| file.write @string_raw.gsub(',',"#{i}\n") }
|
||||
assert File.exists?(filepath)
|
||||
end
|
||||
|
||||
fred = TextMate::Complete.new
|
||||
|
||||
assert_equal(@string_raw.split(',').uniq.length * 3, fred.choices.map{|c| c['display']}.length )
|
||||
end
|
||||
#
|
||||
def test_should_override_split_with_extension
|
||||
ENV['TM_COMPLETIONS_SPLIT'] = ','
|
||||
ENV['TM_COMPLETIONS_FILE'] = '/tmp/completions_test.plist'
|
||||
|
||||
File.open(ENV['TM_COMPLETIONS_FILE'],'w'){|file| file.write @plist_raw }
|
||||
assert File.exists?(ENV['TM_COMPLETIONS_FILE'])
|
||||
|
||||
fred = TextMate::Complete.new
|
||||
assert_equal(['moo', 'foo', 'bar'], fred.choices.map{|c| c['display']})
|
||||
end
|
||||
#
|
||||
def test_should_get_extra_chars_from_var
|
||||
ENV['TM_COMPLETIONS_SPLIT']=','
|
||||
ENV['TM_COMPLETIONS'] = @string_raw
|
||||
ENV['TM_COMPLETIONS_EXTRACHARS'] = '.'
|
||||
|
||||
fred = TextMate::Complete.new
|
||||
assert_equal('.', fred.extra_chars)
|
||||
end
|
||||
#
|
||||
def test_should_get_extra_chars_from_plist
|
||||
ENV['TM_COMPLETIONS_SPLIT']='plist'
|
||||
ENV['TM_COMPLETIONS'] = @plist_raw
|
||||
|
||||
assert_nil(ENV['TM_COMPLETIONS_EXTRACHARS'])
|
||||
|
||||
fred = TextMate::Complete.new
|
||||
assert_equal('.', fred.extra_chars)
|
||||
end
|
||||
# TODO: should_fix_image_paths
|
||||
=begin
|
||||
def test_should_fix_image_paths
|
||||
ENV['TM_COMPLETIONS_SPLIT'] = 'plist'
|
||||
ENV['TM_COMPLETIONS'] = @plist_raw
|
||||
ENV['TM_BUNDLE_SUPPORT'] = '/tmp'
|
||||
ENV['TM_SUPPORT_PATH'] = '/tmp'
|
||||
|
||||
images = OSX::PropertyList.load(@plist_raw)['images']
|
||||
|
||||
FileUtils.mkdir_p "#{ENV['TM_SUPPORT_PATH']}/#{TextMate::Complete::IMAGES_FOLDER_NAME}"
|
||||
images.each_pair do |name,path|
|
||||
File.open("#{ENV['TM_SUPPORT_PATH']}/#{TextMate::Complete::IMAGES_FOLDER_NAME}/#{path}", 'w'){ |file| file.write('') }
|
||||
end
|
||||
|
||||
TextMate::Complete.new.images.each_pair do |name,path|
|
||||
assert File.exists?(path)
|
||||
end
|
||||
|
||||
end
|
||||
=end
|
||||
def test_should_apply_prefix
|
||||
ENV.delete 'TM_COMPLETIONS'
|
||||
assert_nil(ENV['TM_COMPLETIONS'])
|
||||
ENV.delete 'TM_COMPLETIONS_SPLIT'
|
||||
assert_nil(ENV['TM_COMPLETIONS_SPLIT'])
|
||||
|
||||
@json_raw = <<-'JSON'
|
||||
{
|
||||
"extra_chars": "-_$.",
|
||||
"tool_tip_prefix":"prefix",
|
||||
"suggestions": [
|
||||
{ "display": ".moo", "image": "", "insert": "(${1:one}, ${2:one}, ${3:three}${4:, ${5:five}, ${6:six}})", "tool_tip": "moo(one, two, four[, five])\n This method does something or other maybe.\n Insert longer description of it here." },
|
||||
{ "display": "foo", "image": "", "insert": "(${1:one}, \"${2:one}\", ${3:three}${4:, ${5:five}, ${6:six}})", "tool_tip": "foo(one, two)\n This method does something or other maybe.\n Insert longer description of it here." },
|
||||
{ "display": "bar", "image": "", "insert": "(${1:one}, ${2:one}, \"${3:three}\"${4:, \"${5:five}\", ${6:six}})", "tool_tip": "bar(one, two[, three])\n This method does something or other maybe.\n Insert longer description of it here." }
|
||||
],
|
||||
"images": {
|
||||
"String" : "String.png",
|
||||
"RegExp" : "RegExp.png",
|
||||
"Number" : "Number.png",
|
||||
"Array" : "Array.png",
|
||||
"Function": "Function.png",
|
||||
"Object" : "Object.png",
|
||||
"Node" : "Node.png",
|
||||
"NodeList": "NodeList.png"
|
||||
}
|
||||
}
|
||||
JSON
|
||||
|
||||
ENV['TM_COMPLETIONS_SPLIT']='json'
|
||||
ENV['TM_COMPLETIONS'] = @json_raw
|
||||
fred = TextMate::Complete.new
|
||||
assert_equal(3, fred.choices.length)
|
||||
assert fred.choices.first['tool_tip'].match(/^prefix/)
|
||||
end
|
||||
#
|
||||
def test_should_show_tooltip_without_inserting_anything
|
||||
# This method passes if it shows a tooltip when selecting a menu-item
|
||||
# and DOESN'T insert anything or cause the document think anything has changed
|
||||
ENV.delete 'TM_COMPLETIONS'
|
||||
assert_nil(ENV['TM_COMPLETIONS'])
|
||||
ENV.delete 'TM_COMPLETIONS_SPLIT'
|
||||
assert_nil(ENV['TM_COMPLETIONS_SPLIT'])
|
||||
|
||||
ENV['TM_COMPLETIONS_SPLIT']='json'
|
||||
ENV['TM_COMPLETIONS'] = @json_raw
|
||||
fred = TextMate::Complete.new
|
||||
assert_equal(3, fred.choices.length)
|
||||
|
||||
TextMate::Complete.new.tip!
|
||||
end
|
||||
#
|
||||
def test_tip_should_look_for_the_current_word_and_then_try_the_closest_function_name
|
||||
ENV.delete 'TM_COMPLETIONS'
|
||||
assert_nil(ENV['TM_COMPLETIONS'])
|
||||
ENV.delete 'TM_COMPLETIONS_SPLIT'
|
||||
assert_nil(ENV['TM_COMPLETIONS_SPLIT'])
|
||||
|
||||
ENV['TM_COMPLETIONS_SPLIT']='json'
|
||||
ENV['TM_COMPLETIONS'] = @json_raw
|
||||
fred = TextMate::Complete.new
|
||||
assert_equal(3, fred.choices.length)
|
||||
|
||||
TextMate::Complete.new.tip!
|
||||
#
|
||||
# This test passes if, when run, you see the tooltip for closest function
|
||||
# Be sure to more your caret around and try a few times
|
||||
# Showing a menu is a fail
|
||||
#
|
||||
# foo( bar( ), '.moo' )
|
||||
# ^ Caret here should give the tip for 'foo'
|
||||
# ^ Caret here should give the tip for 'bar'
|
||||
# ^ Caret here should give the tip for 'bar'
|
||||
# ^ Caret here should give the tip for '.moo'
|
||||
# foo( bar(one,two,foo), '.moo' )
|
||||
# foo['bar']
|
||||
end
|
||||
#
|
||||
end
|
||||
|
||||
end#if
|
||||
Reference in New Issue
Block a user