Now on revision 112446. ------------------------------------------------------------ revno: 112446 committer: Leo Liu branch nick: trunk timestamp: Fri 2013-05-03 15:52:17 +0800 message: * progmodes/octave.el (user-error): Alias to error if not defined. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-05-03 07:22:26 +0000 +++ lisp/ChangeLog 2013-05-03 07:52:17 +0000 @@ -8,6 +8,7 @@ (octave-help-file, octave-help-function): New button types. (octave-help): New command and bind it to C-h ;. (octave-find-definition): New command and bind it to M-. + (user-error): Alias to error if not defined. 2013-05-02 Leo Liu === modified file 'lisp/progmodes/octave.el' --- lisp/progmodes/octave.el 2013-05-03 07:22:26 +0000 +++ lisp/progmodes/octave.el 2013-05-03 07:52:17 +0000 @@ -36,6 +36,9 @@ ;;; For emacs < 24.3. (require 'newcomment) +(eval-and-compile + (unless (fboundp 'user-error) + (defalias 'user-error 'error))) (eval-when-compile (unless (fboundp 'setq-local) (defmacro setq-local (var val) ------------------------------------------------------------ revno: 112445 committer: Leo Liu branch nick: trunk timestamp: Fri 2013-05-03 15:22:26 +0800 message: * progmodes/octave.el (octave-completing-read) (octave-goto-function-definition): New helpers. (octave-help-buffer): New user variable. (octave-help-file, octave-help-function): New button types. (octave-help): New command and bind it to C-h ;. (octave-find-definition): New command and bind it to M-. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-05-03 04:47:08 +0000 +++ lisp/ChangeLog 2013-05-03 07:22:26 +0000 @@ -2,6 +2,12 @@ * progmodes/octave.el (octave-font-lock-keywords): Do not dehighlight 'end' in comments or strings. + (octave-completing-read, octave-goto-function-definition): New + helpers. + (octave-help-buffer): New user variable. + (octave-help-file, octave-help-function): New button types. + (octave-help): New command and bind it to C-h ;. + (octave-find-definition): New command and bind it to M-. 2013-05-02 Leo Liu === modified file 'lisp/progmodes/octave.el' --- lisp/progmodes/octave.el 2013-05-03 04:47:08 +0000 +++ lisp/progmodes/octave.el 2013-05-03 07:22:26 +0000 @@ -156,6 +156,7 @@ (defvar octave-mode-map (let ((map (make-sparse-keymap))) + (define-key map "\M-." 'octave-find-definition) (define-key map "\e\n" 'octave-indent-new-comment-line) (define-key map "\M-\C-q" 'octave-indent-defun) (define-key map "\C-c\C-p" 'octave-previous-code-line) @@ -167,6 +168,7 @@ (define-key map "\C-c]" 'smie-close-block) (define-key map "\C-c/" 'smie-close-block) (define-key map "\C-c;" 'octave-update-function-file-comment) + (define-key map "\C-hd" 'octave-help) (define-key map "\C-c\C-f" 'octave-insert-defun) (define-key map "\C-c\C-il" 'octave-send-line) (define-key map "\C-c\C-ib" 'octave-send-block) @@ -584,7 +586,9 @@ (defvar inferior-octave-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map comint-mode-map) + (define-key map "\M-." 'octave-find-definition) (define-key map "\t" 'comint-dynamic-complete) + (define-key map "\C-hd" 'octave-help) (define-key map "\M-?" 'comint-dynamic-list-filename-completions) (define-key map "\C-c\C-l" 'inferior-octave-dynamic-list-input-ring) (define-key map [menu-bar inout list-history] @@ -870,6 +874,25 @@ (delete-horizontal-space) (insert (concat " " octave-continuation-string)))) +(defun octave-completing-read () + (let ((def (or (thing-at-point 'symbol) + (save-excursion + (skip-syntax-backward "-(") + (thing-at-point 'symbol))))) + (completing-read + (format (if def "Function (default %s): " + "Function: ") def) + (inferior-octave-completion-table) + nil nil nil nil def))) + +(defun octave-goto-function-definition () + "Go to the first function definition." + (when (save-excursion + (goto-char (point-min)) + (re-search-forward octave-function-header-regexp nil t)) + (goto-char (match-beginning 3)) + (match-string 3))) + (defun octave-function-file-p () "Return non-nil if the first token is \"function\". The value is (START END NAME-START NAME-END) of the function." @@ -1445,6 +1468,92 @@ (mapconcat 'identity inferior-octave-output-list "\n"))) (terpri))) + + +(defcustom octave-help-buffer "*Octave Help*" + "Buffer name for `octave-help'." + :type 'string + :group 'octave + :version "24.4") + +(define-button-type 'octave-help-file + 'follow-link t + 'action #'help-button-action + 'help-function (lambda (fn) + (find-file fn) + (octave-goto-function-definition))) + +(define-button-type 'octave-help-function + 'follow-link t + 'action (lambda (b) + (octave-help + (buffer-substring (button-start b) (button-end b))))) + +(defvar help-xref-following) + +(defun octave-help (fn) + "Display the documentation of FN." + (interactive (list (octave-completing-read))) + (inferior-octave-send-list-and-digest + (list (format "help \"%s\"\n" fn))) + (let ((lines inferior-octave-output-list)) + (when (string-match "error: \\(.*\\)$" (car lines)) + (error "%s" (match-string 1 (car lines)))) + (with-help-window octave-help-buffer + (princ (mapconcat 'identity lines "\n")) + (with-current-buffer octave-help-buffer + ;; Bound to t so that `help-buffer' returns current buffer for + ;; `help-setup-xref'. + (let ((help-xref-following t)) + (help-setup-xref (list 'octave-help fn) + (called-interactively-p 'interactive))) + ;; Note: can be turned off by suppress_verbose_help_message. + ;; + ;; Remove boring trailing text: Additional help for built-in functions + ;; and operators ... + (goto-char (point-max)) + (when (search-backward "\n\n\n" nil t) + (goto-char (match-beginning 0)) + (delete-region (point) (point-max))) + ;; File name highlight + (goto-char (point-min)) + (when (re-search-forward "from the file \\(.*\\)$" + (line-end-position) + t) + (let ((file (match-string 1))) + (replace-match "" nil nil nil 1) + (insert "`") + (help-insert-xref-button (file-name-nondirectory file) + 'octave-help-file file) + (insert "'"))) + ;; Make 'See also' clickable + (with-syntax-table octave-mode-syntax-table + (when (re-search-forward "^\\s-*See also:" nil t) + (while (re-search-forward "\\_<\\(?:\\sw\\|\\s_\\)+\\_>" nil t) + (make-text-button (match-beginning 0) + (match-end 0) + :type 'octave-help-function)))))))) + +(defvar find-tag-marker-ring) + +(defun octave-find-definition (fn) + "Find the definition of FN." + (interactive (list (octave-completing-read))) + (inferior-octave-send-list-and-digest + ;; help NAME is more verbose + (list (format "\ +if iskeyword(\"%s\") disp(\"`%s' is a keyword\") else which(\"%s\") endif\n" + fn fn fn))) + (let* ((line (car inferior-octave-output-list)) + (file (when (and line (string-match "from the file \\(.*\\)$" line)) + (match-string 1 line)))) + (if (not file) + (user-error "%s" (or line (format "`%s' not found" fn))) + (require 'etags) + (ring-insert find-tag-marker-ring (point-marker)) + (find-file file) + (octave-goto-function-definition)))) + (provide 'octave) ;;; octave.el ends here ------------------------------------------------------------ revno: 112444 committer: Leo Liu branch nick: trunk timestamp: Fri 2013-05-03 12:47:08 +0800 message: * progmodes/octave.el (octave-font-lock-keywords): Do not dehighlight 'end' in comments or strings. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-05-02 23:03:00 +0000 +++ lisp/ChangeLog 2013-05-03 04:47:08 +0000 @@ -1,3 +1,8 @@ +2013-05-03 Leo Liu + + * progmodes/octave.el (octave-font-lock-keywords): Do not + dehighlight 'end' in comments or strings. + 2013-05-02 Leo Liu * progmodes/octave.el (octave-mode-syntax-table): Correct syntax === modified file 'lisp/progmodes/octave.el' --- lisp/progmodes/octave.el 2013-05-02 23:03:00 +0000 +++ lisp/progmodes/octave.el 2013-05-03 04:47:08 +0000 @@ -100,30 +100,34 @@ (list ;; Fontify all builtin keywords. (cons (concat "\\_<\\(" - (regexp-opt (append octave-reserved-words + (regexp-opt (append octave-reserved-words octave-text-functions)) - "\\)\\_>") - 'font-lock-keyword-face) + "\\)\\_>") + 'font-lock-keyword-face) ;; Note: 'end' also serves as the last index in an indexing expression. ;; Ref: http://www.mathworks.com/help/matlab/ref/end.html - '("\\_" (0 (save-excursion - (condition-case nil - (progn - (goto-char (match-beginning 0)) - (backward-up-list) - (unless (memq (char-after) '(?\( ?\[ ?\{)) - font-lock-keyword-face)) - (error font-lock-keyword-face))) - t)) + '((lambda (limit) + (while (re-search-forward "\\_" limit 'move) + (let ((beg (match-beginning 0)) + (end (match-end 0))) + (unless (octave-in-string-or-comment-p) + (unwind-protect + (progn + (goto-char beg) + (backward-up-list) + (when (memq (char-after) '(?\( ?\[ ?\{)) + (put-text-property beg end 'face nil))) + (goto-char end))))) + nil)) ;; Fontify all builtin operators. (cons "\\(&\\||\\|<=\\|>=\\|==\\|<\\|>\\|!=\\|!\\)" - (if (boundp 'font-lock-builtin-face) - 'font-lock-builtin-face - 'font-lock-preprocessor-face)) + (if (boundp 'font-lock-builtin-face) + 'font-lock-builtin-face + 'font-lock-preprocessor-face)) ;; Fontify all function declarations. (list octave-function-header-regexp - '(1 font-lock-keyword-face) - '(3 font-lock-function-name-face nil t))) + '(1 font-lock-keyword-face) + '(3 font-lock-function-name-face nil t))) "Additional Octave expressions to highlight.") (defun octave-syntax-propertize-function (start end)