2

I use js2-mode with emacs-prelude, imenu displays the list of functions and I can collapse and uncollapse the functions defined in a regular js file like this

function testFunction1(){
    console.debug("test function");
}

function testFunction2(arg1, arg2){
    console.debug("test function2");
}

It however doesn't work on a angular js file

'use strict';
app.controller('TestController', ['$scope', 'TestService',
    function($scope, TestService){

        function testFunction1(obj) {
            console.debug("Test Function");
        }

        var testVariable = {
            'field1': 'val1',
            'field2': 'val2'
        };

        $scope.scopeFunction1 = function(){
            console.debug("Scope Function ");
       };

       $scope.scopeVar ={
        'field1': 'val1',
        'field2': 'val2'
    };
}]);

It doesn't recognize - testFunction1 or scopeFunction1 as a function, they are not displayed on the iMenu and I couldn't collapse/uncollapse them. How can we configure emacs for working with angular js files.

nicael
  • 1,598
  • 2
  • 13
  • 20
tutysara
  • 33
  • 5
  • What do you mean by "*collapse and uncollapse*" in the context of Imenu? – Drew Oct 26 '14 at 20:37
  • show/hide function body, it is invoked by pressing C-c C-f and calls (js2-mode-toggle-hide-functions) – tutysara Oct 26 '14 at 20:59
  • I got the latest js2-mode from here - https://github.com/redguardtoo/js2-mode/blob/master/js2-mode.el and added this in my config to fix imenu -- (defun tutysara/js2-mode-imenu-config() (interactive) (setq imenu-generic-expression js2-extra-imenu-generic-expression)) (add-hook 'js2-mode-hook 'tutysara/js2-mode-config). Still looking for help on hide/show functions and blocks. – tutysara Oct 27 '14 at 17:24
  • Ask any remaining questions (e.g. about hide/show) separately. – Drew Oct 27 '14 at 21:22

2 Answers2

3

Solution 1 (recommended):

A perfect solution for BOTH js-mode and js2-mode:

https://github.com/redguardtoo/emacs.d/blob/master/lisp/init-javascript.el

Screen shot, enter image description here

Solution 2 (js2-mode only):

It's a little bit more complex to set up, but the imenu item will display more context and I GUESS imenu functions extracted this way could be hide/show by js2-mode:

you need change js2-imenu-extension-styles, please make sure you've installed latest js2-mode. Only in latest version of js2-mode, that variable is configurable since my pull request was merged just a few days ago (https://github.com/mooz/js2-mode/commit/31c49e02b58de7aa959b1cd03fe8381c545da810)

For :call-re part, use the regex I provided in solution1, for other parts, just copy/paste from samples defined in https://github.com/mooz/js2-mode/blob/master/js2-imenu-extras.el

In summary, solution 1 is simpler to setup which I recommend. solution 2 is more official and will give you more context information. so your choice.

BTW, for anyone who are interested in tech details,

  1. This article explains the problem, my plan of the solution: http://blog.binchen.org/posts/why-emacs-is-better-editor-part-two.html

  2. This is the actual implementation, after one month discussion with the js2-mode maintainers https://github.com/mooz/js2-mode/pull/169

  3. you can use BOTH solution 1 and solution 2, the imenu items in solution 2 will take priority, you will NOT get duplicated imenu items

chen bin
  • 4,781
  • 18
  • 36
1

Someone else can provide more details, hopefully.

The short answer, as far as I can see, is that the js2-mode.el code uses a parser to add items to the Imenu menu, and this parser does not recognize the function definitions you have that are nested inside function($scope, TestService) - which is itself inside an array argument passed to app.controller etc.

Imenu typically fills out its menu by regexp matching. But js2-mode.el uses a parser to do that. You will need to descend into the details of this parsing to see what the problem is in this case. (At least it's not obvious to me, at first view.)

Drew
  • 75,699
  • 9
  • 109
  • 225
  • I am new to emacs, I started understanding a bit of elisp. If you can you point me to any dotemacs repo where this is done, it will be useful. – tutysara Oct 26 '14 at 22:04
  • Sorry, I don't understand the question. I meant only that you would need to investigate more closely what the code in `js2-mode.el` does. I followed it a bit in the Emacs debugger (using command `debug-on-entry`), but I didn't spend a lot of time on it. Essentially, instead of matching a regexp, the Lisp code parses the js code and fills the Imenu menu with entries (e.g. `(testFunction . 1)`) as it goes. – Drew Oct 27 '14 at 01:30
  • If you are looking for help understanding Emacs Lisp, start with `C-h i` and choose the `Emacs Lisp Intro` manual, and read a bit. For using the Emacs debugger, see the [Elisp manual, node `Debugger`](https://www.gnu.org/software/emacs/manual/html_node/elisp/Debugger.html#Debugger), which you can, again, get to via `C-h i`. – Drew Oct 27 '14 at 01:33
  • I guess someone had did it already, on searching I found this recent pull request - https://github.com/mooz/js2-mode/pull/169. It is still not merged into js2-mode. – tutysara Oct 27 '14 at 15:48