Skip to content
This repository has been archived by the owner on Sep 17, 2018. It is now read-only.

Commit

Permalink
Basic imenu support - makes things like `textmate-goto-symbol' work!
Browse files Browse the repository at this point in the history
  • Loading branch information
defunkt committed Mar 8, 2010
1 parent c5ffe04 commit 30d2af5
Showing 1 changed file with 79 additions and 1 deletion.
80 changes: 79 additions & 1 deletion coffee-mode.el
Expand Up @@ -179,7 +179,10 @@ print the compiled JavaScript.")
(defvar coffee-this-regexp "@\\w*\\|this")

;; Assignment
(defvar coffee-assign-regexp "\\(\\w\\|\\.\\|_\\| \\|$\\)+?:")
(defvar coffee-assign-regexp "\\(\\(\\w\\|\\.\\|_\\| \\|$\\)+?\\):")

;; Lambda
(defvar coffee-lambda-regexp "\\((.+)\\)?\s *\\(->\\|=>\\)")

;; Booleans
(defvar coffee-boolean-regexp "\\b\\(true\\|false\\|yes\\|no\\|on\\|off\\)\\b")
Expand Down Expand Up @@ -247,6 +250,76 @@ For detail, see `comment-dwim'."
(when coffee-debug-mode
(apply 'message (append (list string) args))))

;;
;; imenu support
;;

;; This is a pretty naive but workable way of doing it. First we look
;; for any lines that starting with `coffee-assign-regexp' that include
;; `coffee-lambda-regexp' then add those tokens to the list.
;;
;; Should cover cases like these:
;;
;; minus: (x, y) -> x - y
;; String::length: -> 10
;; block: ->
;; print('potion')
;;
;; Next we look for any line that starts with `class' or
;; `coffee-assign-regexp' followed by `{` and drop into a
;; namespace. This means we search one indentation level deeper for
;; more assignments and add them to the alist prefixed with the
;; namespace name.
;;
;; Should cover cases like these:
;;
;; class Person
;; print: ->
;; print 'My name is ' + this.name + '.'
;;
;; class Policeman extends Person
;; constructor: (rank) ->
;; @rank: rank
;; print: ->
;; print 'My name is ' + this.name + " and I'm a " + this.rank + '.'
;;
;; app = {
;; window: {width: 200, height: 200}
;; para: -> 'Welcome.'
;; button: -> 'OK'
;; }

(defun coffee-imenu-create-index ()
"Create an imenu index of all methods in the buffer."
(interactive)

;; This function is called within a `save-excursion' so we're safe.
(beginning-of-buffer)

(let ((index-alist '()) assign pos func)
;; Go through every assignment that includes -> or => on the same
;; line.
(while (re-search-forward
(concat "^\\s *"
coffee-assign-regexp
".+?"
coffee-lambda-regexp)
(point-max)
t)

;; The token being assigned. `Please.print:` will be
;; `Please.print`, `block:` will be `block`, etc.
(setd assign (match-string 1))

;; The position of the match in the buffer.
(setd pos (match-beginning 0))

;; Add this to the alist. Done.
(push (cons assign pos) index-alist))

;; Return the alist.
index-alist))

;;
;; Indentation
;;
Expand Down Expand Up @@ -390,10 +463,15 @@ line? Returns `t' or `nil'. See the README for more details."
(make-local-variable 'indent-line-function)
(setq indent-line-function 'coffee-indent-line)

;; imenu
(make-local-variable 'imenu-create-index-function)
(setq imenu-create-index-function 'coffee-imenu-create-index)

;; no tabs
(setq indent-tabs-mode nil)

;; clear memory
;; TODO: make these accurate
(setq coffee-keywords-regexp nil)
(setq coffee-types-regexp nil)
(setq coffee-constants-regexp nil)
Expand Down

0 comments on commit 30d2af5

Please sign in to comment.