I've been trying in vain the past few days to get Vim to recognize tags in my JS file. My problem is very similar to this other question: How to view javascript tags in vim using tagbar + jsctags + tern_for_vim + ctags_exuberant? and I have a similar setup:
- Universal ctags installed (since exuberant-ctags seems to be not updating as much)
- Jsctags via a global gem
- tern_for_vim
I've tried to debug the tagbar plugin and it seems to call jsctags
fine and does not print any errors. I've also tried to run jsctags
via the command line with this command per the git repo's readme:
find . -type f -iregex ".*\.js$" -not -path "./node_modules/*" -exec jsctags {} -f \; | sed '/^$/d' | sort > tags
This generates a tags file fine, and if I run echo tagfiles()
the output gives me ['tags']
, which means it's pointing to the correct tag file location (confirmed using :pwd
). :tag
gives me tag stack empty
and if I put my cursor over any method or object and hit Ctrl-]
I'll get tag not found: Controller
.
I've referenced Can't get Ctags working and How to view javascript tags in vim using tagbar + jsctags + tern_for_vim + ctags_exuberant?, both of which don't have solutions, hence the question here.
Attaching a section of my .vimrc
to show my list of plugins, js file and .ctags
if relevant:
.vimrc
Plugin 'gmarik/Vundle.vim' " Plugin Management
Plugin 'tmhedberg/matchit' " Matching configuration for %
Plugin 'jelera/vim-javascript-syntax' " Additional JS syntax highlighting
Plugin 'tpope/vim-surround' "provides mappings to easily delete, change and add surroundings like quotes, parenths etc
Plugin 'plasticboy/vim-markdown' "Markdown support
Plugin 'davidoc/taskpaper.vim' "Taskpaper support
Plugin 'tpope/vim-commentary' " Simple commenting in vim
Plugin 'scrooloose/nerdtree' "Tree navigation
Plugin 'Xuyuanp/nerdtree-git-plugin' "Nerdtree git tags for files support
Plugin 'scrooloose/syntastic' "Syntax check
Plugin 'majutsushi/tagbar' "Browse the tags of the current file and get an overview of its structure.
Plugin 'ctrlpvim/ctrlp.vim' "Full path fuzzy file, buffer, mru, tag, ... finder for Vim.
Plugin 'bling/vim-airline' "Statusbar
Plugin 'tpope/vim-fugitive' "Vim wrapper, allow for git viewing in airline
Plugin 'vim-airline/vim-airline-themes' "Airline themes
Plugin 'burnettk/vim-angular' " Angular functionality
Plugin 'jiangmiao/auto-pairs' "Insert or delete brackets, parens, quotes in pair
Plugin 'Yggdroot/indentLine' "A vim plugin to display the indention levels with thin vertical lines
Plugin 'altercation/vim-colors-solarized' "Solarized color theme
Plugin 'chriskempson/vim-tomorrow-theme' "Tomorrow color theme
Plugin 'w0ng/vim-hybrid' "Hybrid Solarized, codecademy, Jellybeans, and Tomorrow-Night
Plugin 'Valloric/YouCompleteMe' " Code completion
Plugin 'marijnh/tern_for_vim' "Vim tern usage, greatly improves YouCompleteMe JS use
Plugin 'elzr/vim-json' " JSON highlighting
Plugin 'rking/ag.vim' " Advanced searching
" For JavaScript development
Plugin 'pangloss/vim-javascript' "Javascript syntax highlighting
Plugin 'moll/vim-node' " Node js
Plugin 'groenewege/vim-less' " Less syntax
Plugin 'othree/javascript-libraries-syntax.vim' " Javascript syntax library highlighting
Plugin 'othree/jspc.vim' " Javascript parameter completion
Plugin '1995eaton/vim-better-javascript-completion' " Expansion of vim's javascript syntax file for HTML5
.ctags
--recurse=yes
--exclude=.git
--exclude=vendor/*
--exclude=node_modules/*
--exclude=db/*
--exclude=log/*
--exclude=*.min.js
--exclude=*.css
--langdef=less
--langmap=less:.less
--regex-less=/^[ t ]*.([A-Za-z0-9_-]+)/1/c,class,classes/
--regex-less=/^[ t ]*#([A-Za-z0-9_-]+)/1/i,id,ids/
--regex-less=/^[ t ]*(([A-Za-z0-9_-]+[ tn, ]+)+){/1/t,tag,tags/
--regex-less=/^[ t ]*@medias+([A-Za-z0-9_-]+)/1/m,media,medias/
--languages=-JavaScript
--langdef=js
--langmap=js:.js
--regex-js=/[ \t. ]([A-Z][A-Z0-9._$]+)[ \t ]*[=:][ \t ]*([0-9"'\[\{]|null)/\1/n,constant/
--regex-js=/\.([A-Za-z0-9._$]+)[ \t ]*=[ \t ]*\{/\1/o,object/
--regex-js=/['"]*([A-Za-z0-9_$]+)['"]*[ \t ]*:[ \t ]*\{/\1/o,object/
--regex-js=/([A-Za-z0-9._$]+)\[["']([A-Za-z0-9_$]+)["']\][ \t ]*=[ \t ]*\{/\1\.\2/o,object/
--regex-js=/([A-Za-z0-9._$]+)[ \t ]*=[ \t ]*\(function\(\)/\1/c,class/
--regex-js=/['"]*([A-Za-z0-9_$]+)['"]*:[ \t ]*\(function\(\)/\1/c,class/
--regex-js=/class[ \t ]+([A-Za-z0-9._$]+)[ \t ]*/\1/c,class/
--regex-js=/([A-Za-z$][A-Za-z0-9_$()]+)[ \t ]*=[ \t ]*[Rr]eact.createClass[ \t ]*\(/\1/c,class/
--regex-js=/([A-Z][A-Za-z0-9_$]+)[ \t ]*=[ \t ]*[A-Za-z0-9_$]*[ \t ]*[{(]/\1/c,class/
--regex-js=/([A-Z][A-Za-z0-9_$]+)[ \t ]*:[ \t ]*[A-Za-z0-9_$]*[ \t ]*[{(]/\1/c,class/
--regex-js=/([A-Za-z$][A-Za-z0-9_$]+)[ \t ]*=[ \t ]*function[ \t ]*\(/\1/f,function/
--regex-js=/(function)*[ \t ]*([A-Za-z$_][A-Za-z0-9_$]+)[ \t ]*\([^)]*\)[ \t ]*\{/\2/f,function/
--regex-js=/['"]*([A-Za-z$][A-Za-z0-9_$]+)['"]*:[ \t ]*function[ \t ]*\(/\1/m,method/
--regex-js=/([A-Za-z0-9_$]+)\[["']([A-Za-z0-9_$]+)["']\][ \t ]*=[ \t ]*function[ \t ]*\(/\2/m,method/
js file
define(['jquery',
'lodash',
'backbone',
'mobile/chart/model/chart-model',
'mobile/chart/views/chart-view',
'services/analytic-service'],
function ($, _, Backbone, ChartModel, ChartView, AnalyticsService) {
'use strict';
// not exactly like the full chart controller
//jshint unused:false
function log(msg) {
console.log('%c' + msg, 'font-size:12pt; color: #30F');
}
//jshint unused:true
function newGuid(noDashes) {
var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
return noDashes ? guid.replace(/-/g, '') : guid;
}
function parseJson(jsonString) {
//our JSON may include long integer numbers that can have more digits
// than the JS Number type supports. These numbers are all IDs so we
// can convert them to strings before parsing.
var massagedJson = jsonString.replace(/([^\\]{1})\":(?: {0,})([0-9]{16,})([^\.])/g, "$1\":\"$2\"$3");
//JSON docs are not supposed to have NaN or nan but some of our servers are adding them anyway.
massagedJson = massagedJson.replace(/([^\\]{1})\":(?: {0,})(nan)/gi, "$1\":\"NaN\"");
return JSON.parse(massagedJson);
}
function processHistoricalData(data) {
if(this.isDestroyed) {
return;
}
var bars = data.bars,
subscription = this.subscriptions[data.subscriptionId];
if (_.isUndefined(this.earliestTickReceived) && data.requestIsFinal) {
this.model.set('lastError', 'Contract has no historical data');
this.model.set('noHistoricalData', true);
return;
}
this.model.set({
'requestIsPending': data.requestIsPending,
'requestIsFinal': data.requestIsFinal,
'requestIsCompleted': data.requestIsCompleted,
'lastError': null,
'retryingConnection': false,
'remainingRetries': 5
});
if (bars && bars.length > 0) {
if (bars.length > 0) {
// The server can return an array of bars which only have inside market updates. In this
// case the converted bars array will be empty.
subscription.earliestTickReceived = new Date(bars[0].tickTime);
}
} else {
bars = [];
}
this.view.historicalData(bars);
}
function processLiveData(data) {
if(this.isDestroyed) {
return;
}
this.view.liveData(data.bars);
}
function isVAP(name) {
return (name.indexOf('VAP') > -1);
}
var Controller = function (Host, $chartEl) {
var self = this,
uniqueId = null,
onErrorHandler = null,
onClosedHandler = null,
onConnectedHandler = null,
onHistoricalDataHandler = null,
onLiveDataHandler = null;
this.analyticsService = new AnalyticsService({
analyticsUrl: analyticsUrl,
accessToken: Host.getAuthToken(),
logDebug: function () {
console.log.apply(console, arguments);
}
});
this.model = new ChartModel();
uniqueId = this.model.getUniqueId();
this.view = new ChartView({
model: this.model,
el: $chartEl[0],
$el: $chartEl,
controller: this
});
onErrorHandler = function (err) {
self.Host.dismissProgress();
self.model.set('retryingConnection', false);
self.model.set('firstHistoricalCallbackIteration', true);
self.model.set('retryingConnection', false);
if (err && err.error) {
self.model.set('lastError', err.error);
self.Host.log('Analytics Server Error: ' + err.error);
}
else {
self.model.set('lastError', 'Analytics Server Error');
self.Host.log('Analytics Server Error, unspecified reason');
}
};
});
Thanks all and please let me know if I need to provide any additional details.
tags
file, and processes that data independently. Everything tags-related it does or doesn't is completely separated from anything tag-related Vim does or doesn't. So… is your question about Vim or about Tagbar?~/.ctags
file. So… is your question about JSCtags or about Universal Ctags?tags
file to adhere to a specific format described in:help ctags
. Does the output of your shell command fit that format?:echo taglist(".")
to output what Vim could put together from the files intagfiles()
. Can you find your objects/methods, there?