CoffeeTags 0.0.2.2 → 0.0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -0
- data/lib/CoffeeTags/formatter.rb +10 -2
- data/lib/CoffeeTags/parser.rb +82 -18
- data/lib/CoffeeTags/version.rb +1 -1
- data/spec/fixtures/blockcomment.coffee +7 -0
- data/spec/fixtures/blockcomment.ctags +7 -0
- data/spec/fixtures/out.test-two.ctags +10 -1
- data/spec/fixtures/out.test.ctags +7 -1
- data/spec/parser_spec.rb +38 -0
- metadata +9 -7
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
A simple tool for generating CoffeeScript tags (Ctags compatible).
|
4
4
|
|
5
|
+
[![Build Status](https://secure.travis-ci.org/lukaszkorecki/CoffeeTags.png?branch=master)](http://travis-ci.org/lukaszkorecki/CoffeeTags)
|
6
|
+
|
5
7
|
|
6
8
|
### Example + Screenshot
|
7
9
|
Showing only functions (right) or with variables included (left)
|
data/lib/CoffeeTags/formatter.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Coffeetags
|
2
2
|
class Formatter
|
3
|
+
# Generates CTAGS header
|
4
|
+
# @returns [String] ctags header
|
3
5
|
def self.header
|
4
6
|
return [
|
5
7
|
"!_TAG_FILE_FORMAT 2 /extended format/",
|
@@ -11,6 +13,10 @@ module Coffeetags
|
|
11
13
|
].map { |h| "#{h}\n"}.join ''
|
12
14
|
end
|
13
15
|
|
16
|
+
# New Formatter class
|
17
|
+
#
|
18
|
+
# @param [String] file file name
|
19
|
+
# @param [Array] tree parse tree for given file generated by Coffeetags::Parser
|
14
20
|
def initialize file, tree =[]
|
15
21
|
@file = file
|
16
22
|
@tree = tree
|
@@ -26,6 +32,7 @@ module Coffeetags
|
|
26
32
|
end
|
27
33
|
|
28
34
|
|
35
|
+
# Helper function for formatting a source line into regex
|
29
36
|
def regex_line line
|
30
37
|
"/#{line}/;\""
|
31
38
|
end
|
@@ -47,8 +54,9 @@ module Coffeetags
|
|
47
54
|
|
48
55
|
def parse_tree
|
49
56
|
@lines = @tree.map do | content|
|
50
|
-
|
51
|
-
end
|
57
|
+
line_to_string content unless content[:line].nil? or content[:name].blank?
|
58
|
+
end
|
59
|
+
@lines.reject{|l| l.nil? }
|
52
60
|
end
|
53
61
|
|
54
62
|
|
data/lib/CoffeeTags/parser.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
module Coffeetags
|
2
2
|
class Parser
|
3
3
|
attr_reader :tree
|
4
|
+
# Creates a new parser
|
5
|
+
#
|
6
|
+
# @param [String] source source of the CoffeeScript file
|
7
|
+
# @param [Bool] include_vars include objects in generated tree (default false)
|
8
|
+
# @return [Coffeetags::Parser]
|
4
9
|
def initialize source, include_vars = false
|
5
10
|
@include_vars = include_vars
|
6
11
|
@source = source
|
@@ -17,12 +22,46 @@ module Coffeetags
|
|
17
22
|
@var_regex = /([@a-zA-Z0-9_]*)\s*[=:]{1}\s*$/
|
18
23
|
@token_regex = /([@a-zA-Z0-9_]*)\s*[:=]{1}/
|
19
24
|
@iterator_regex = /^\s*for\s*([a-zA-Z0-9_]*)\s*/
|
25
|
+
@comment_regex = /^\s*#/
|
26
|
+
@block_comment_regex = /^\s*###/
|
27
|
+
@comment_lines = mark_commented_lines
|
20
28
|
end
|
21
29
|
|
30
|
+
|
31
|
+
# Mark line numbers as commented out
|
32
|
+
# either by single line comment (#)
|
33
|
+
# or block comments (###~###)
|
34
|
+
def mark_commented_lines
|
35
|
+
[].tap do |reg|
|
36
|
+
in_block_comment = false
|
37
|
+
@source.each_with_index do |line, index|
|
38
|
+
line_no = index+1
|
39
|
+
|
40
|
+
in_block_comment = !(in_block_comment) if line =~ @block_comment_regex
|
41
|
+
reg << line_no if in_block_comment
|
42
|
+
reg << line_no if line =~ @comment_regex and not in_block_comment
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Detect current line level based on indentation
|
48
|
+
# very useful in parsing, since CoffeeScript's syntax
|
49
|
+
# depends on whitespace
|
50
|
+
# @param [String] line currently parsed line
|
51
|
+
# @return [Integer]
|
22
52
|
def line_level line
|
23
53
|
line.match(/^[ \t]*/)[0].gsub("\t", " ").split('').length
|
24
54
|
end
|
25
55
|
|
56
|
+
# Generate current scope path, for example:
|
57
|
+
# e ->
|
58
|
+
# f ->
|
59
|
+
# z ->
|
60
|
+
# Scope path for function z would be:
|
61
|
+
# window.e.f
|
62
|
+
# @param [Hash, nil] _el element of a prase tree (last one for given tree is used by default)
|
63
|
+
# @param [Array, nil] _tree parse tree (or currently built)
|
64
|
+
# @returns [String] string representation of scope for given element
|
26
65
|
def scope_path _el = nil, _tree = nil
|
27
66
|
bf = []
|
28
67
|
tree = (_tree || @tree)
|
@@ -38,40 +77,63 @@ module Coffeetags
|
|
38
77
|
end
|
39
78
|
end
|
40
79
|
bf.uniq.reverse.join('.')
|
80
|
+
end
|
41
81
|
|
82
|
+
# Helper function for generating parse tree elements for given
|
83
|
+
# line and regular expression
|
84
|
+
#
|
85
|
+
# @param [String] line source line currently being parsed
|
86
|
+
# @param [RegExp] regex regular expression for matching a syntax element
|
87
|
+
# @param [Integer] level current indentation/line level
|
88
|
+
# @param [Hash, {}] additional_fields additional fields which need to be added to generated element
|
89
|
+
# @returns [Hash,nil] returns a parse tree element consiting of:
|
90
|
+
# :name of the element
|
91
|
+
# indentation :level of the element
|
92
|
+
def item_for_regex line, regex, level, additional_fields={}
|
93
|
+
if item = line.match(regex)
|
94
|
+
entry_for_item = {
|
95
|
+
:name => item[1],
|
96
|
+
:level => level
|
97
|
+
}
|
98
|
+
entry_for_item.merge(additional_fields)
|
99
|
+
end
|
42
100
|
end
|
43
101
|
|
102
|
+
# Parse the source and create a tags tree
|
103
|
+
# @note this method mutates @tree instance variable of Coffeetags::Parser instance
|
104
|
+
# @returns self it can be chained
|
44
105
|
def execute!
|
45
106
|
line_n = 0
|
46
107
|
level = 0
|
47
|
-
# indentify scopes
|
48
108
|
@source.each_line do |line|
|
49
109
|
line_n += 1
|
110
|
+
# indentify scopes
|
50
111
|
level = line_level line
|
51
112
|
|
52
113
|
# ignore comments!
|
53
|
-
next if
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
114
|
+
next if @comment_lines.include? line_n
|
115
|
+
|
116
|
+
# extract elements for given line
|
117
|
+
[
|
118
|
+
@class_regex,
|
119
|
+
@proto_meths,
|
120
|
+
@var_regex
|
121
|
+
].each do |regex|
|
122
|
+
mt = item_for_regex line, regex, level
|
123
|
+
@tree << mt unless mt.nil?
|
58
124
|
end
|
59
125
|
|
60
|
-
if(_proto = line.match @proto_meths)
|
61
|
-
@tree << { :name => _proto[1], :level => level }
|
62
|
-
end
|
63
126
|
|
64
|
-
|
65
|
-
|
66
|
-
|
127
|
+
# does this line contain a block?
|
128
|
+
mt = item_for_regex line, @block, level, :kind => 'b'
|
129
|
+
@tree << mt unless mt.nil?
|
67
130
|
|
68
|
-
if(_block = line.match @block)
|
69
|
-
@tree << { :name => _block[1], :level => level , :kind => 'b'}
|
70
|
-
end
|
71
131
|
|
132
|
+
# instance variable or iterator (for/in)?
|
72
133
|
token = line.match(@token_regex )
|
73
134
|
token ||= line.match(@iterator_regex)
|
74
135
|
|
136
|
+
# we have found something!
|
75
137
|
if not token.nil?
|
76
138
|
o = {
|
77
139
|
:name => token[1],
|
@@ -85,8 +147,8 @@ module Coffeetags
|
|
85
147
|
# - if a line containes a line like: element.getElement('type=[checkbox]').lol()
|
86
148
|
is_in_string = line =~ /.*['"].*#{token[1]}.*=.*["'].*/
|
87
149
|
|
88
|
-
|
89
|
-
|
150
|
+
# - scope access and comparison in if x == 'lol'
|
151
|
+
is_in_comparison = line =~ /::|==/
|
90
152
|
|
91
153
|
# - objects with blank parent (parser bug?)
|
92
154
|
has_blank_parent = o[:parent] =~ /\.$/
|
@@ -95,7 +157,7 @@ module Coffeetags
|
|
95
157
|
is_previous_not_the_same = !(@tree.last and @tree.last[:name] == o[:name] and @tree.last[:level] == o[:level])
|
96
158
|
|
97
159
|
if is_in_string.nil? and is_in_comparison.nil? and has_blank_parent.nil? and is_previous_not_the_same
|
98
|
-
o[:kind]
|
160
|
+
o[:kind] = line =~ /[:=]{1}.*[-=]\>/ ? 'f' : 'o'
|
99
161
|
o[:parent] = scope_path o
|
100
162
|
o[:parent] = @fake_parent if o[:parent].empty?
|
101
163
|
|
@@ -103,7 +165,9 @@ module Coffeetags
|
|
103
165
|
@tree << o if o[:kind] == 'o' and @include_vars
|
104
166
|
end
|
105
167
|
end
|
168
|
+
# get rid of duplicate entries
|
106
169
|
@tree.uniq!
|
170
|
+
self # chain!
|
107
171
|
end
|
108
172
|
end
|
109
173
|
end
|
data/lib/CoffeeTags/version.rb
CHANGED
@@ -0,0 +1,7 @@
|
|
1
|
+
!_TAG_FILE_FORMAT 2 /extended format/
|
2
|
+
!_TAG_FILE_SORTED 0 /0=unsorted, 1=sorted, 2=foldcase/
|
3
|
+
!_TAG_PROGRAM_AUTHOR Łukasz Korecki /lukasz@coffeesounds.com/
|
4
|
+
!_TAG_PROGRAM_NAME CoffeeTags //
|
5
|
+
!_TAG_PROGRAM_URL https://github.com/lukaszkorecki/CoffeeTags /GitHub repository/
|
6
|
+
!_TAG_PROGRAM_VERSION 0.0.2.4 //
|
7
|
+
echo2 spec/fixtures/blockcomment.coffee /echo2/;" f lineno:7 object:window type:function
|
@@ -3,20 +3,29 @@
|
|
3
3
|
!_TAG_PROGRAM_AUTHOR Łukasz Korecki /lukasz@coffeesounds.com/
|
4
4
|
!_TAG_PROGRAM_NAME CoffeeTags //
|
5
5
|
!_TAG_PROGRAM_URL https://github.com/lukaszkorecki/CoffeeTags /GitHub repository/
|
6
|
-
!_TAG_PROGRAM_VERSION 0.0.2.
|
6
|
+
!_TAG_PROGRAM_VERSION 0.0.2.4 //
|
7
7
|
bump spec/fixtures/test.coffee /bump/;" f lineno:1 object:window type:function
|
8
|
+
|
8
9
|
ho spec/fixtures/test.coffee /ho/;" f lineno:5 object:Wat type:function
|
10
|
+
|
9
11
|
bump spec/fixtures/test.coffee /bump/;" f lineno:10 object:Wat.ho.@lolWat type:function
|
10
12
|
bump_up spec/fixtures/test.coffee /bump_up/;" f lineno:12 object:Wat.ho.@lolWat type:function
|
11
13
|
@filter spec/fixtures/test.coffee /@filter/;" f lineno:14 object:Wat.ho type:function
|
12
14
|
_loop spec/fixtures/test.coffee /_loop/;" f lineno:19 object:window type:function
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
13
19
|
bound_func spec/fixtures/test.coffee /bound_func/;" f lineno:41 object:window type:function
|
14
20
|
beam_magnum spec/fixtures/test.coffee /beam_magnum/;" f lineno:44 object:window type:function
|
21
|
+
|
15
22
|
constructor spec/fixtures/campfire.coffee /constructor/;" f lineno:8 object:Campfire type:function
|
16
23
|
handlers spec/fixtures/campfire.coffee /handlers/;" f lineno:14 object:Campfire type:function
|
24
|
+
|
17
25
|
onSuccess spec/fixtures/campfire.coffee /onSuccess/;" f lineno:16 object:Campfire.handlers.resp type:function
|
18
26
|
onFailure spec/fixtures/campfire.coffee /onFailure/;" f lineno:24 object:Campfire.handlers.resp type:function
|
19
27
|
rooms spec/fixtures/campfire.coffee /rooms/;" f lineno:29 object:Campfire type:function
|
20
28
|
roomInfo spec/fixtures/campfire.coffee /roomInfo/;" f lineno:34 object:Campfire type:function
|
21
29
|
recent spec/fixtures/campfire.coffee /recent/;" f lineno:40 object:Campfire type:function
|
30
|
+
|
22
31
|
bump spec/fixtures/campfire.coffee /bump/;" f lineno:46 object:Test type:function
|
@@ -3,12 +3,18 @@
|
|
3
3
|
!_TAG_PROGRAM_AUTHOR Łukasz Korecki /lukasz@coffeesounds.com/
|
4
4
|
!_TAG_PROGRAM_NAME CoffeeTags //
|
5
5
|
!_TAG_PROGRAM_URL https://github.com/lukaszkorecki/CoffeeTags /GitHub repository/
|
6
|
-
!_TAG_PROGRAM_VERSION 0.0.2.
|
6
|
+
!_TAG_PROGRAM_VERSION 0.0.2.4 //
|
7
7
|
bump spec/fixtures/test.coffee /bump/;" f lineno:1 object:window type:function
|
8
|
+
|
8
9
|
ho spec/fixtures/test.coffee /ho/;" f lineno:5 object:Wat type:function
|
10
|
+
|
9
11
|
bump spec/fixtures/test.coffee /bump/;" f lineno:10 object:Wat.ho.@lolWat type:function
|
10
12
|
bump_up spec/fixtures/test.coffee /bump_up/;" f lineno:12 object:Wat.ho.@lolWat type:function
|
11
13
|
@filter spec/fixtures/test.coffee /@filter/;" f lineno:14 object:Wat.ho type:function
|
12
14
|
_loop spec/fixtures/test.coffee /_loop/;" f lineno:19 object:window type:function
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
13
19
|
bound_func spec/fixtures/test.coffee /bound_func/;" f lineno:41 object:window type:function
|
14
20
|
beam_magnum spec/fixtures/test.coffee /beam_magnum/;" f lineno:44 object:window type:function
|
data/spec/parser_spec.rb
CHANGED
@@ -167,5 +167,43 @@ describe 'CoffeeTags::Parser' do
|
|
167
167
|
subject[:parent].should == '_loop'
|
168
168
|
end
|
169
169
|
end
|
170
|
+
context 'Block comments' do
|
171
|
+
let(:bc_file) { 'spec/fixtures/blockcomment.coffee'}
|
172
|
+
let(:bc_ctags_file) { 'spec/fixtures/blockcomment.ctags'}
|
173
|
+
let(:blockcomment_file) { File.read(bc_file)}
|
174
|
+
let(:blockcomment_tree) {
|
175
|
+
[{:level=>0,
|
176
|
+
:parent=>"window",
|
177
|
+
:source=>"echo2 :-> console.log 'echo'",
|
178
|
+
:line=>7,
|
179
|
+
:kind=>"f",
|
180
|
+
:name=>"echo2"}]
|
181
|
+
}
|
182
|
+
|
183
|
+
subject {
|
184
|
+
parser = Coffeetags::Parser.new(blockcomment_file, true)
|
185
|
+
parser.execute!
|
186
|
+
parser
|
187
|
+
}
|
188
|
+
|
189
|
+
it 'ignores block comments when parsing the contents' do
|
190
|
+
subject.tree.first.should == blockcomment_tree.first
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
context 'top-down test' do
|
195
|
+
let(:blockcomment_ctags){ File.read(bc_ctags_file) }
|
196
|
+
subject {
|
197
|
+
Coffeetags::Utils.run 'test_bc.out', nil, bc_file
|
198
|
+
File.read 'test_bc.out'
|
199
|
+
}
|
200
|
+
|
201
|
+
after(:all) { `rm test_bc.out` }
|
202
|
+
|
203
|
+
it 'ignores block comments in output' do
|
204
|
+
subject.should == blockcomment_ctags
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
170
208
|
end
|
171
209
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: CoffeeTags
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 79
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
9
|
- 2
|
10
|
-
-
|
11
|
-
version: 0.0.2.
|
10
|
+
- 4
|
11
|
+
version: 0.0.2.4
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- "\xC5\x81ukasz Korecki"
|
@@ -16,8 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2012-03-
|
20
|
-
default_executable:
|
19
|
+
date: 2012-03-12 00:00:00 Z
|
21
20
|
dependencies: []
|
22
21
|
|
23
22
|
description: CoffeeTags generates ctags compatibile tags for CoffeeScript.
|
@@ -45,6 +44,8 @@ files:
|
|
45
44
|
- lib/CoffeeTags/parser.rb
|
46
45
|
- lib/CoffeeTags/version.rb
|
47
46
|
- spec/coffeetags_spec.rb
|
47
|
+
- spec/fixtures/blockcomment.coffee
|
48
|
+
- spec/fixtures/blockcomment.ctags
|
48
49
|
- spec/fixtures/campfire.coffee
|
49
50
|
- spec/fixtures/campfire.js
|
50
51
|
- spec/fixtures/campfire.js.tags
|
@@ -60,7 +61,6 @@ files:
|
|
60
61
|
- tagbar-info.markdown
|
61
62
|
- test.rb
|
62
63
|
- vim/tagbar-coffee.vim.erb
|
63
|
-
has_rdoc: true
|
64
64
|
homepage: http://github.com/lukaszkorecki/CoffeeTags
|
65
65
|
licenses: []
|
66
66
|
|
@@ -90,12 +90,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
90
|
requirements: []
|
91
91
|
|
92
92
|
rubyforge_project: CoffeeTags
|
93
|
-
rubygems_version: 1.
|
93
|
+
rubygems_version: 1.8.16
|
94
94
|
signing_key:
|
95
95
|
specification_version: 3
|
96
96
|
summary: tags generator for CoffeeScript
|
97
97
|
test_files:
|
98
98
|
- spec/coffeetags_spec.rb
|
99
|
+
- spec/fixtures/blockcomment.coffee
|
100
|
+
- spec/fixtures/blockcomment.ctags
|
99
101
|
- spec/fixtures/campfire.coffee
|
100
102
|
- spec/fixtures/campfire.js
|
101
103
|
- spec/fixtures/campfire.js.tags
|