Permalink
Browse files

Very most basicest functionality.

  • Loading branch information...
0 parents commit 4f19ea560cdea303fe7734ea92c0b5210ecee9e5 @othiym23 committed Nov 23, 2012
Showing with 184 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +11 −0 .jshintrc
  3. +20 −0 README.md
  4. +7 −0 bin/jstags
  5. +103 −0 index.js
  6. +35 −0 package.json
  7. +7 −0 test/basic.tap.js
@@ -0,0 +1 @@
+node_modules
@@ -0,0 +1,11 @@
+{
+ "es5": true,
+ "laxcomma": true,
+ "eqeqeq": true,
+ "forin": true,
+ "immed": true,
+ "latedef": true,
+ "newcap": true,
+ "nonew": true,
+ "node": true
+}
@@ -0,0 +1,20 @@
+## jstags
+
+Using tagbar in vim is awesome. Using ctags with JavaScript is not awesome.
+`jstags` uses the power of [Esprima](http://esprima.org) to make tagbar more
+awesome.
+
+### installation
+
+```
+npm install -g jstags
+```
+
+### usage
+
+```
+jstags *.js
+```
+
+Right now, the results just get dumped to stdout. Eventually it'll be closer
+to command-line compatible with Exuberant CTags. Probably after it actually works.
@@ -0,0 +1,7 @@
+#!/usr/bin/env node
+
+var argv = require('optimist').argv
+ , jstags = require('jstags')
+ ;
+
+jstags(argv._);
103 index.js
@@ -0,0 +1,103 @@
+'use strict';
+
+var fs = require('fs')
+ , esprima = require('esprima')
+ , visit = require('estraverse').traverse
+ ;
+
+function requireTag(filename, node) {
+ var name = node.id.name;
+ var startLine = node.loc.start.line - 1;
+ var pattern = startLine + '/\\<' + node.id.name + '\\>/;"';
+
+ return [name, filename, pattern, 'i', 'lineno:' + (startLine + 1)].join('\t');
+}
+
+function isRequire(node) {
+ return node &&
+ node.type === 'CallExpression' &&
+ node.callee &&
+ node.callee.type === 'Identifier' &&
+ node.callee.name === 'require';
+}
+
+function isObjectExpression(node) {
+ return node &&
+ node.type === 'ObjectExpression';
+}
+
+function objectFromMemberExpression(node) {
+ var child = node.init;
+ while (child.type === 'MemberExpression' && child.object) {
+ child = child.object;
+ }
+
+ return child;
+}
+
+function methodTags(filename, node, object) {
+ object.properties.forEach(function (property) {
+ if (property.value.type === 'FunctionExpression') {
+ var name = node.id.name + '.' + property.key.name;
+ var startLine = property.key.loc.start.line - 1;
+ var pattern = startLine + '/\\<' + property.key.name + '\\>/;"';
+
+ console.log([name, filename, pattern, 'm', 'lineno:' + (startLine + 1)].join('\t'));
+ }
+ });
+}
+
+var nodeVisitors = {
+ 'VariableDeclarator' : function (filename, node) {
+ if (!node.init) return;
+
+ var target;
+ if (isRequire(node.init)) {
+ console.log(requireTag(filename, node));
+ }
+ else if (node.init.type === 'MemberExpression') {
+ target = objectFromMemberExpression(node);
+ if (isRequire(target)) {
+ console.log(requireTag(filename, node));
+ }
+ }
+ else if (node.init.type === 'AssignmentExpression') {
+ target = node.init.right;
+ if (isObjectExpression(target)) {
+ methodTags(filename, node, target);
+ }
+ }
+ }
+};
+
+function visitor (filename) {
+ return {
+ enter : function enter(node, stack) {
+ var handler = nodeVisitors[node.type];
+ if (handler) handler(filename, node);
+ // else console.dir(node);
+ }
+ };
+}
+
+function header() {
+ return "!_TAG_FILE_FORMAT 2 /extended format/\n" +
+ "!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/\n" +
+ "!_TAG_PROGRAM_AUTHOR Forrest L Norvell /ogd@aoaioxxysz.net/\n" +
+ "!_TAG_PROGRAM_NAME jstags //\n" +
+ "!_TAG_PROGRAM_URL http://github.com/othiym23/jstags /github repository/\n" +
+ "!_TAG_PROGRAM_VERSION 0.0.0 //";
+}
+
+console.log(header());
+
+module.exports = function tagFiles(filenames) {
+ filenames.forEach(function (filename) {
+ fs.readFile(filename, function (err, source) {
+ if (err) return console.error("Error reading helper: %s", err);
+
+ var ast = esprima.parse(source, {loc : true});
+ visit(ast, visitor(filename));
+ });
+ });
+};
@@ -0,0 +1,35 @@
+{
+ "name": "jstags",
+ "version": "0.0.1",
+ "description": "ctags-like tag generator for JavaScript and Node.js",
+ "main": "index.js",
+ "scripts": {
+ "test": "tap test"
+ },
+ "bin": {
+ "jstags": "./bin/jstags"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/othiym23/jstags.git"
+ },
+ "keywords": [
+ "esprima",
+ "ctags",
+ "ast",
+ "vim",
+ "javascript",
+ "analysis",
+ "source"
+ ],
+ "author": "Forrest L Norvell <ogd@aoaioxxysz.net>",
+ "license": "BSD",
+ "dependencies": {
+ "esprima": "~1.0.2",
+ "estraverse": "0.0.3",
+ "optimist": "~0.3.5"
+ },
+ "devDependencies": {
+ "tap": "~0.3.2"
+ }
+}
@@ -0,0 +1,7 @@
+'use strict';
+
+var test = require('tap').test
+ , jstags = require('jstags')
+ ;
+
+test("there will be tests here eventually, honest");

0 comments on commit 4f19ea5

Please sign in to comment.