Merge from CEDET upstream (8564).
[bpt/emacs.git] / lisp / cedet / semantic / ctxt.el
index 2608dfb..efaec4f 100644 (file)
@@ -1,7 +1,6 @@
 ;;; semantic/ctxt.el --- Context calculations for Semantic tools.
 
-;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-;;   2007, 2008, 2009, 2010, 2011  Free Software Foundation, Inc.
+;; Copyright (C) 1999-2013 Free Software Foundation, Inc.
 
 ;; Author: Eric M. Ludlam <zappo@gnu.org>
 ;; Keywords: syntax
@@ -107,7 +106,7 @@ Return non-nil if there is no upper context."
   (let ((start (point)))
     (if (semantic-up-context)
        t
-      ;; Go over the list, and back over the end parenthisis.
+      ;; Go over the list, and back over the end parenthesis.
       (condition-case nil
          (progn
            (forward-sexp 1)
@@ -155,7 +154,7 @@ Return non-nil if there is no upper context."
 (define-overloadable-function semantic-get-local-variables (&optional point)
   "Get the local variables based on POINT's context.
 Local variables are returned in Semantic tag format.
-This can be overriden with `get-local-variables'."
+This can be overridden with `get-local-variables'."
   ;; Disable parsing messages
   (let ((semantic--progress-reporter nil))
     (save-excursion
@@ -358,6 +357,87 @@ beginning and end of a command."
            (def-edebug-spec semantic-with-buffer-narrowed-to-command
              (def-body))))
 
+(define-overloadable-function semantic-ctxt-end-of-symbol (&optional point)
+  "Move point to the end of the current symbol under POINT.
+This skips forward over symbols in a complex reference.
+For example, in the C statement:
+  this.that().entry;
+
+If the cursor is on 'this', will move point to the ; after entry.")
+
+(defun semantic-ctxt-end-of-symbol-default (&optional point)
+  "Move poin to the end of the current symbol under POINT.
+This will move past type/field names when applicable.
+Depends on `semantic-type-relation-separator-character', and will
+work on C like languages."
+  (if point (goto-char point))
+  (let* ((fieldsep1 (mapconcat (lambda (a) (regexp-quote a))
+                              semantic-type-relation-separator-character
+                              "\\|"))
+        ;; NOTE: The [ \n] expression below should used \\s-, but that
+        ;; doesn't work in C since \n means end-of-comment, and isn't
+        ;; really whitespace.
+        (fieldsep (concat "[ \t\n\r]*\\(" fieldsep1 "\\)[ \t\n\r]*\\(\\w\\|\\s_\\)"))
+        (case-fold-search semantic-case-fold)
+        (continuesearch t)
+        (end nil)
+        )
+      (with-syntax-table semantic-lex-syntax-table
+       (cond ((looking-at "\\w\\|\\s_")
+              ;; In the middle of a symbol, move to the end.
+              (forward-sexp 1))
+             ((looking-at fieldsep1)
+              ;; We are in a fine spot.. do nothing.
+              nil
+              )
+             ((save-excursion
+                (and (condition-case nil
+                         (progn (forward-sexp -1)
+                                (forward-sexp 1)
+                                t)
+                       (error nil))
+                     (looking-at fieldsep1)))
+              (setq symlist (list ""))
+              (forward-sexp -1)
+              ;; Skip array expressions.
+              (while (looking-at "\\s(") (forward-sexp -1))
+              (forward-sexp 1))
+             )
+       ;; Set the current end marker.
+       (setq end (point))
+
+       ;; Cursor is at the safe end of some symbol.  Look until we
+       ;; find the logical end of this current complex symbol.
+       (condition-case nil
+           (while continuesearch
+             ;; If there are functional arguments, arrays, etc, skip them.
+             (when (looking-at "\\s(")
+               (forward-sexp 1))
+
+             ;; If there is a field separator, then skip that, plus
+             ;; the next expected symbol.
+             (if (not (looking-at fieldsep1))
+                 ;; We hit the end.
+                 (error nil)
+
+               ;; Skip the separator and the symbol.
+               (goto-char (match-end 0))
+               
+               (if (looking-at "\\w\\|\\s_")
+                   ;; Skip symbols
+                   (forward-sexp 1)
+                 ;; No symbol, exit the search...
+                 (setq continuesearch nil))
+                 
+               (setq end (point)))
+               
+             ;; Cont...
+             )
+         
+         ;; Restore position if we go to far....
+         (error (goto-char end)) )
+
+       )))
 
 (define-overloadable-function semantic-ctxt-current-symbol (&optional point)
   "Return the current symbol the cursor is on at POINT in a list.
@@ -392,7 +472,7 @@ Depends on `semantic-type-relation-separator-character'."
                 ;; In the middle of a symbol, move to the end.
                 (forward-sexp 1))
                ((looking-at fieldsep1)
-                ;; We are in a find spot.. do nothing.
+                ;; We are in a fine spot.. do nothing.
                 nil
                 )
                ((save-excursion
@@ -411,7 +491,7 @@ Depends on `semantic-type-relation-separator-character'."
          ;; Set our end point.
          (setq end (point))
 
-         ;; Now that we have gotten started, lets do the rest.
+         ;; Now that we have gotten started, let's do the rest.
          (condition-case nil
              (while (save-excursion
                       (forward-char -1)
@@ -619,5 +699,4 @@ means that the first symbol might be:
 ;; generated-autoload-load-name: "semantic/ctxt"
 ;; End:
 
-;; arch-tag: 04f3ae3c-78bb-40ca-b112-ba77f5e4ea88
 ;;; semantic/ctxt.el ends here