Thursday, June 03, 2004

php-complete-function

Dissapppointed by the poor php-mode for emacs, I am trying to improve it by adding php-complete-function. I can now complete most of the php functions (methods of objects are missing), but I'm struggling on how to mix the php functions with user defined functions from TAGS. I somehow can't get the right tags-completion-table and merge it with my php-completion-table.

(defcustom php-completion-buffer-file "/home/tekai/emacs/php_functions"
  "*Path to the file which contains the function names"
  :type 'string
  :group 'php)

(defvar php-completion-table nil
  "Obarray of tag names defined in current tags table.")
;; Define function name completion function

(defun php-complete-function ()
  "Complete the function name at the point from known PHP functions."
  (interactive)
  (let ((pattern (funcall (or find-tag-default-function
                              (get major-mode 'find-tag-default-function)
                              'find-tag-default)))
        beg
        completion
        (php-functions (php-completion-table)))
    (search-backward pattern)
    (setq beg (point))
    (forward-char (length pattern))
    (setq completion (try-completion pattern php-functions nil))
    (cond ((eq completion t))
          ((null completion)
           (message "Can't find completion for this \"%s\"" pattern)
           (ding))
          ((not (string= pattern completion))
           (delete-region beg (point))
           (insert completion))
          (t
           (message "Making completion list...")
           (with-output-to-temp-buffer "*Completions*"
             (display-completion-list
              (all-completions pattern php-functions)))
           (message "Making completion list...%s" "done"))))
  ;;(complete-tag)
  ;;(message "php-complete-function not implemented yet")
  ;; how to read the list of functions from a separate file?
  )

(defun php-completion-table ()
  (or php-completion-table
      (let ((table (make-vector 1022 0))
            (php-completion-buffer (find-file-noselect php-completion-buffer-file))
            (tags-table (if (functionp 'tags-completion-table)
                            (progn (visit-tags-table-buffer)
                                   (tags-completion-table))
                            nil)))
        (save-excursion
          (set-buffer php-completion-buffer)
          (goto-char (point-min))
          (while (re-search-forward
                  "^\\([-a-zA-Z0-9_.]+\\)\n"
                  nil t)
            (intern (buffer-substring (match-beginning 1) (match-end 1))
                    table)))
         (if tags-table
             ;; Combine the tables.
             (mapatoms (lambda (sym) (intern (symbol-name sym) tags-table))
                   php-completion-table))
        (setq php-completion-table table))))

The php_functions file has one function name per line.

Aside: I find the poor quality of php-mode somewhat strange, maybe I shouldn't compare it with slime, but I expected it to do better, PHP is not that new. But maybe most PHP coders don't grasp (e)lisp, use IDEs and are just codemonkeys who doing are doing most of their work copy&paste. But really why is the php-mode that bad?

No comments: