emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: arguments hint


From: Paul Pogonyshev
Subject: Re: arguments hint
Date: Fri, 4 Jun 2004 16:33:06 +0300
User-agent: KMail/1.6.52

I made some experiments with `eldoc-mode' for C.  Below are the
results.  The thing is very hackish and has many loose ends,
but is already usable.  It will print hints for the function of
your project (i.e. it doesn't use any special tables for other
functions) based on the tags.  Contrary to what I expected, it
works quite fast.

Btw, as a side effect it opens extra buffers without being asked
for it.  This may be considered a serious drawback.

Comments are welcome.

Paul


;;  To use: eval the below code and then `c-turn-on-eldoc-mode'
;;          in a C buffer.


(defvar c-eldoc-reserved-words
  (list "if" "else" "switch" "while" "for" "sizeof"))

(defun c-turn-on-eldoc-mode ()
  (interactive)
  (set (make-local-variable 'eldoc-print-current-symbol-info-function)
       'c-print-current-symbol-info)
  (turn-on-eldoc-mode))

(defun c-function-and-argument (&optional limit)
  (let* ((return-point   (point))
         (literal-limits (c-literal-limits))
         (literal-type   (c-literal-type literal-limits)))
    (prog2
        (when (eq literal-type 'string)
          (goto-char (car literal-limits))
          (setq literal-type nil))
        (if literal-type
            nil
          (c-save-buffer-state ((argument-index 1))
            (while (or (eq (c-forward-token-2 -1 t limit) 0)
                       (when (eq (char-before) ?\[)
                         (backward-char)
                         t))
              (when (eq (char-after) ?,)
                (setq argument-index (1+ argument-index))))
            (c-backward-syntactic-ws)
            (when (eq (char-before) ?\()
              (backward-char)
              (c-forward-token-2 -1)
              (when (looking-at "[a-zA-Z_][a-zA-Z_0-9]*")
                (cons (buffer-substring-no-properties
                       (match-beginning 0) (match-end 0))
                      argument-index)))))
      (goto-char return-point))))

(defun c-format-arguments-string (arguments index)
  (let ((paren-pos (string-match "(" arguments))
        (pos       0))
    (when (string-match "(" arguments)
      (setq arguments (replace-regexp-in-string
                       "\\\\?[[:space:]\\\n]" " "
                       (substring arguments paren-pos))
            arguments (replace-regexp-in-string "\\s-+" " "  arguments)
            arguments (replace-regexp-in-string " *, *" ", " arguments)
            arguments (replace-regexp-in-string "( +"   "("  arguments)
            arguments (replace-regexp-in-string " +)"   ")"  arguments))
      (while (and (> index 1) pos
                  (not (string= (substring arguments (+ pos 2) (+ pos 6))
                                "...)")))
        (setq pos (string-match "," arguments (1+ pos))
              index (1- index)))
      (when (and pos
                 (setq pos (string-match "[^ ,()]" arguments pos)))
        (add-text-properties pos (string-match "[,)]" arguments pos)
                             '(face bold) arguments))
      arguments)))

(defun c-print-current-symbol-info ()
  (let* ((current-function-cons (c-function-and-argument (- (point) 1000)))
         (current-function      (car current-function-cons))
         (current-buffer        (current-buffer))
         (tag-buffer)
         (function-name-point)
         (arguments)
         (type-face             'font-lock-type-face))
    (when (and current-function
               (not (member current-function c-eldoc-reserved-words)))
      (when (setq tag-buffer (find-tag-noselect current-function))
        (prog2
            (set-buffer tag-buffer)
            (when (search-forward current-function (line-end-position) t)
              (setq function-name-point (point))
              (forward-sexp)
              (setq arguments (buffer-substring-no-properties
                               function-name-point (point)))
              (goto-char function-name-point)
              (backward-char (length current-function))
              (c-skip-ws-backward)
              (setq function-name-point (point))
              (search-backward-regexp "[};/#]" (point-min) t)
              (if (= (char-after) ?#)
                  (let ((is-define          (looking-at "#[[:space:]]*define"))
                        (preprocessor-point (point)))
                    (while (prog2 (end-of-line)
                                  (= (char-before) ?\\)
                             (forward-char)))
                    (when (and is-define (> (point) function-name-point))
                      (goto-char preprocessor-point)
                      (setq type-face 'font-lock-preprocessor-face)))
                (forward-char)
                (when (looking-back "//")
                  (end-of-line)))
              (c-skip-ws-forward)
              (concat (propertize (buffer-substring-no-properties
                                   (point)
                                   function-name-point)
                                  'face type-face)
                      "  "
                      (propertize current-function
                                  'face 'font-lock-function-name-face)
                      " "
                      (c-format-arguments-string arguments
                                                 (cdr current-function-cons))))
          (goto-char (mark t))
          (set-buffer current-buffer))))))




reply via email to

[Prev in Thread] Current Thread [Next in Thread]