English 中文(简体)
How can I make vim s taglist plugin show useful information for javascript?
原标题:

I ve recently abandoned mouse-driven, platform-specific GUI editors and committed entirely to vim. The experience so far has been fantastic, but I m stuck when it comes to Javascript.

The ever-popular taglist utility (using Exuberant Ctags) has been great for everything but Javascript. With the language s overly-free form and structure, taglist could only pick up a handful of functions when I opened it up -- only those defined in the format:

function FUNCNAME (arg1, arg2) {

but no variables or function objects defined like:

var myFunc = function (arg1, arg2) {

So I googled a bit and found the following definition set for ctags, which I put in my ~/.ctags file:

--langdef=js
--langmap=js:.js
--regex-js=/([A-Za-z0-9._$]+)[ 	]*[:=][ 	]*{/1/,object/
--regex-js=/([A-Za-z0-9._$()]+)[ 	]*[:=][ 	]*function[ 	]*(/1/,function/
--regex-js=/function[ 	]+([A-Za-z0-9._$]+)[ 	]*([^])])/1/,function/
--regex-js=/([A-Za-z0-9._$]+)[ 	]*[:=][ 	]*[/1/,array/
--regex-js=/([^= ]+)[ 	]*=[ 	]*[^""] [^  ]*/1/,string/
--regex-js=/([^= ]+)[ 	]*=[ 	]*[^  ]"[^""]*/1/,string/

After that, running ctags from the command line was fantastic. It found every function and object that I needed it to find.

The problem is that the taglist.vim plugin isn t seeing those new results. When I open my javascript file in vim and hit :TlistToggle, I get the exact same meager handful of functions I got before. I hit u to update the list, with no effect.

Digging into taglist.vim, I found this:

" java language
let s:tlist_def_java_settings =  java;p:package;c:class;i:interface;  .
                                 f:field;m:method 

" javascript language
let s:tlist_def_javascript_settings =  javascript;f:function 

...which implies we re only looking at one specific kind of output from the ctags utility for javascript. Unfortunately, I m not savvy enough with taglist or vim in general (yet) to discover what change I can make to get all those wonderful ctags command-line results to show up in vim.

Help appreciated!

最佳回答

Got it! I dove into the taglist.vim code for awhile, and this is what I found:

taglist.vim forces ctags to use the same filetype that vim is using. So even though the ~/.ctags snippet I found via google is assigning my much-needed definitions to the new "js" language and applying it to files that end in .js, taglist is forcing ctags into using the "JavaScript" filetype that vim is using -- which is built right into ctags already.

The solution is to change the ~/.ctags file from what I ve posted above to this:

--regex-JavaScript=/([A-Za-z0-9._$]+)[ 	]*[:=][ 	]*new[ 	]+Object(/1/o,object/
--regex-JavaScript=/([A-Za-z0-9._$]+)[ 	]*[:=][ 	]*{/1/o,object/
--regex-JavaScript=/([A-Za-z0-9._$()]+)[ 	]*[:=][ 	]*function[ 	]*(/1/f,function/
--regex-JavaScript=/function[ 	]+([A-Za-z0-9._$]+)[ 	]*([^])]*)/1/f,function/
--regex-JavaScript=/([A-Za-z0-9._$]+)[ 	]*[:=][ 	]*new[ 	]+Array(/1/a,array/
--regex-JavaScript=/([A-Za-z0-9._$]+)[ 	]*[:=][ 	]*[/1/a,array/
--regex-JavaScript=/([^= ]+)[ 	]*=[ 	]*[^""] [^  ]*/1/s,string/
--regex-JavaScript=/([^= ]+)[ 	]*=[ 	]*[^  ]"[^""]*/1/s,string/

which alters the pre-existing JavaScript language definition directly, rather than creating a new language definition within ctags. Now, when taglib forces vim s registered filetype, the new definitions are used. Also missing from the previously posted ~/.ctags lines was the "kind" letter that Al mentioned in his answer, so those are included in my updated version as well.

From there, drop the following into your ~/.vimrc to activate the new types:

let g:tlist_javascript_settings =  javascript;s:string;a:array;o:object;f:function 

All-in-all, the new regex lines aren t perfect -- they ll definitely need some tweaking to avoid a lot of false positives, and it might be nice to separate out constants and such. But now, at least, I have the ability to do that :).

Edit: Added instructions on how to activate types without editing the plugin, and vastly improved the main ctags function regex to avoid some false-positives.

Edit 2: Added more array and object definitions to the ctags regex.

问题回答

I ran into this post on a google search, and although your findings are excellent, I think we can improve them. This is the results of a bit of hacking on your solution:

.ctags

--regex-JavaScript=/^var[ 	]+([a-zA-Z0-9_$]+) = [/1/a,array/
--regex-JavaScript=/^var[ 	]+([a-zA-Z0-9_$]+) = {/1/o,object/
--regex-JavaScript=/^var[ 	]+([a-zA-Z0-9_$]+) = (^{^[)+/1/r,var/
--regex-JavaScript=/^[ 	]*(this.)?([A-Za-z0-9_$()]+)[ 	]*[:=][ 	]*function[ 	]*()/2/u,function/
--regex-JavaScript=/^[ 	]*function ([a-z0-9]+[A-Za-z0-9_]*)/1/u,function/
--regex-JavaScript=/^[ 	]*([A-Za-z0-9]+).prototype.([a-z0-9]+[A-Za-z0-9_]*)/1 : 2/u,function/
--regex-JavaScript=/^[ 	]*function ([A-Z]+[A-Za-z0-9_]*)/1/o,object/

.vimrc

let g:tlist_javascript_settings =  javascript;r:var;s:string;a:array;o:object;u:function 

This gets rid of a few more false positives, and adds some more features in, as a tradeoff for getting rid of some of the more problematic regexes. I ll keep updating if I find I need more.

Edit: I ve gotten everything working really nicely now; I feel like this result is solid. The only major deficiency is that it doesn t work on comma separated variable definitions. That seems particularly nasty. Maybe another day. :)

Note also that I changed the .vimrc. This isn t because I m a freak; it s because somehow taglist or ctags or something has some default values set, and if you don t change it, then you get a lot of doubles where functions and vars are concerned, which really drives me insane (I pay super attention to detail.. :P )

Edit: More tweaks. It picks up on prototype function declarations now, and doesn t do some other stupid stuff.

The best-practice solution, which is also very new, neat and easy way to get JavaScript source-code browsing / tag-list in Vim, is using Mozilla s DoctorJS (formerly known as jsctags).

See my answer for this question for more info.

Enjoy. :)

I ve not used javascript or taglist much, but looking through :help taglist-extend, it looks like your definitions (listed above) rename the javascript output to js, so you ll probably need something like (in your vimrc):

let tlist_js_settings =  js;f:function;m:method 

This is assuming that the ctags kind is f for function and m for method. Have a look at your tags file and see what the kind column looks like. By way of example, my C code tags file includes this line:

ADC_CR1_AWDCH_0 .LibraryModulesCMSISHeadersstm32f10x.h  2871;"  d

This is a #define of a symbol ADC_CR1_AWDCH_0, which is in the listed file at line 2871. The d is the ctags kind for a defined name. Hopefully that will give you enough to get you going.

As an aside, I m not sure whether the override will work correctly, so it might be worth naming your file myfile.mjs and changing your langmap to js:.mjs until it s working properly. Then at least you ll know whether your problems are associated with misidentification of files or the actual parsing.

Hi thanks to Tom Frost for his question and research, I think there is a little problem with the 4th line regexp of your final answer:

--regex-JavaScript=/function[ 	]+([A-Za-z0-9._$]+)[ 	]*([^])]*)/1/f,function/

Doesn t worked for me, I pulled it a bit and now works ok:

--regex-JavaScript=/function[ 	]+([A-Za-z0-9._$]+)[ 	]*([^)]*)/1/f,function/

PD. The others answers regexps posted here doesn t work at all at least for me :-?

To avoid duplicate entries from ctags built in javascript support I define js language as in original post and help taglist use ctags with it. I also make sure that tagnames are stripped from some less useful bits (quotes, "this.", ".prototype"). I don t use object/array/string/var regexps, but it s easy to combine my regexps with the other suggestions.

~/.ctags:

--langdef=js
--langmap=js:.js
--regex-js=/[" ]?(this.)?([A-Za-z0-9_$]+)[" ]?((.prototype)?(.[A-Za-z0-9_$]+))?[ 	]*[:=][ 	]*function/25/f,function/
--regex-js=/function[ 	]+([A-Za-z0-9_$]+)/1/f,function/

~/.vimrc:

let g:tlist_javascript_settings =  js;f:function 




相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签