vim-erlang / vim-erlang-tags

Generate Vim tags for Erlang files
https://vim-erlang.github.io
Other
61 stars 23 forks source link

Records with name enclosed with quotes #19

Open civing opened 9 years ago

civing commented 9 years ago

When record name is enclosed with quotes it's not added to the list of tags.

example: test.erl: -module(test). -record(test, {none}). -record('test@', {none}).

tags: !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted/

test ./test.erl /^-\srecord\s(\s*test>/;" r file:

test    ./test.erl  /^-\s*record\s*(\s*test>/;" r   file:
test    ./test.erl  1;" M
test.erl    ./test.erl  1;" F
hcs42 commented 9 years ago

Now records in quotes are found – please let me know if it works as you expected.

civing commented 9 years ago

Hi!

Special records are now added to the tags file. Thats perfect! However, vim can't seem to correctly follow the special records listed in the tags file.

Example:

test.erl: -module(test). -record(test, {none}). record('Bla-bla', {none}).

test() ->
Test = #'Bla-bla',
Test2 = #test.

tags:

Bla-bla ./test.erl /^-\srecord\s(\s*'Bla-bla'/;" r file:

#test   ./test.erl  /^-\s*record\s*(\s*test>/;" r   file:
#test@  ./test.erl  /^-\s*record\s*(\s*'test@'/;"    r   file:
Bla-bla ./test.erl  /^-\s*record\s*(\s*'Bla-bla'/;"  r   file:
test    ./test.erl  /^-\s*record\s*(\s*test>/;" r   file:
test    ./test.erl  /^test>/;" f   file:
test    ./test.erl  1;" M
test.erl    ./test.erl  1;" F
test:test   ./test.erl  /^test>/;" f
test@   ./test.erl  /^-\s*record\s*(\s*'test@'/;"    r   file:

Pressing <C-]> yields for different scenarios:

Placing the cursor over the "B" in #'Bla-bla' will render E426: tag not found: Bla

Placing the cursor over the "-" in #'Bla-bla' will render E426: tag not found: -

Placing the cursor over the "b" in #'Bla-bla' will render E426: tag not found: bla

Is this something that can be fixed in the overriden VimErlangTagsSelect() function?

Many thanks! Per

hcs42 commented 9 years ago

Is this something that can be fixed in the overriden VimErlangTagsSelect() function?

Indeed. Instead of doing "_vawo here, we should do one of two things (I prefer the second one):

The other tricky part is deciding whether we are in a record name with a plain atom syntax or one with a quoted atom syntax. Assuming that you use the vim-erlang syntax file (which is also the one shipped with Vim 7.4), then synIDattr(synID(line('.'), col('.'), 1), 'name') ==# 'erlangQuotedAtom' should do that trick.

Another though I had is that maybe we should also generate #'Bla-bla'-like tags for all records. Even if someone defines a record as record(myrecord, other files might refer to it as #'myrecord'. On the other hand, this would make the tags file even larger (now we have every record twice, this way we would have most of them 3 times).

If you feel like contributing, this is a great opportunity ;) Otherwise (no worries in that case) before I implement the above, you can manually do a vi' before pressing C-], and that should take you to the record definition.

civing commented 9 years ago

I will give it a shot! Bare in mind that I'm new to both Erlang and vim scripting though. :)

civing commented 9 years ago

I did a simple hack for this particular 'Bla-bla' atom. Its a delicate problem since any character is valid in a quoted atom:

An atom is a literal, a constant with name. An atom should be enclosed in single quotes (') if it does not begin with a lower-case letter or if it contains other characters than alphanumeric characters, underscore (_), or @.

I guess one of your solution above is better. In the meantime, maybe my hack will do. Pull request coming up..

hcs42 commented 9 years ago

Its a delicate problem

Indeed :) Making the space character work within record names is especially difficult, because a tag in a tag file cannot contain whitespace. So even my proposal doesn't fix the particular case of the space character.

In the meantime, maybe my hack will do. Pull request coming up..

Unfortunately this PR would break cases where there is no space around a - (or -> or --) token. Consider what happens if we try to follow lists:min in the following function: Vim would actually try to follow -lists:min.

min_max_diff(L) ->
    lists:max(L)-lists:min(A).
civing commented 9 years ago

You are absolutely correct Csaba, sorry for not considering that..