branch: externals/matlab-mode commit 7d0d26a0312cf3a7b0cb07ff982f1b5274f96424 Author: John Ciolfi <john.ciolfi...@gmail.com> Commit: John Ciolfi <john.ciolfi...@gmail.com>
Setup imenu for *.tlc files --- tests/metest-imenu-tlc-files/timestwo.tlc | 23 ++++++ tests/metest-imenu-tlc-files/timestwo_expected.txt | 2 + tests/metest-imenu-tlc.el | 86 ++++++++++++++++++++++ tests/metest.el | 2 + tlc.el | 22 +++--- 5 files changed, 125 insertions(+), 10 deletions(-) diff --git a/tests/metest-imenu-tlc-files/timestwo.tlc b/tests/metest-imenu-tlc-files/timestwo.tlc new file mode 100644 index 0000000000..4816d067aa --- /dev/null +++ b/tests/metest-imenu-tlc-files/timestwo.tlc @@ -0,0 +1,23 @@ +%implements "timestwo" "C" + +%% Function: BlockTypeSetup ================================== +%% +%function BlockTypeSetup(block, system) void + %% Add function prototype to model's header file + %<LibCacheFunctionPrototype... + ("extern void mytimestwo(real_T* in,real_T* out,int_T els);")> + %% Add file that contains "myfile" to list of files to be compiled + %<LibAddToModelSources("myfile")> +%endfunction + +%% Function: Outputs ========================================== +%% +%function Outputs(block, system) Output + /* %<Type> Block: %<Name> */ + %assign outPtr = LibBlockOutputSignalAddr(0, "", "", 0) + %assign inPtr = LibBlockInputSignalAddr(0, "", "",0) + %assign numEls = LibBlockOutputSignalWidth(0) + /* Multiply input by two */ + mytimestwo(%<inPtr>,%<outPtr>,%<numEls>); + +%endfunction diff --git a/tests/metest-imenu-tlc-files/timestwo_expected.txt b/tests/metest-imenu-tlc-files/timestwo_expected.txt new file mode 100644 index 0000000000..93b35ee0c2 --- /dev/null +++ b/tests/metest-imenu-tlc-files/timestwo_expected.txt @@ -0,0 +1,2 @@ +BlockTypeSetup +Outputs diff --git a/tests/metest-imenu-tlc.el b/tests/metest-imenu-tlc.el new file mode 100644 index 0000000000..0cef57b69c --- /dev/null +++ b/tests/metest-imenu-tlc.el @@ -0,0 +1,86 @@ +;;; metest-imenu-tlc.el --- Testing suite for MATLAB Emacs -*- lexical-binding: t -*- +;; +;; Copyright 2025 Free Software Foundation, Inc. +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; + +;;; Commentary: +;; +;; Tests to exercise the tlc--imenu-generic-expression regexp +;; + +;;; Code: + +(require 'tlc) + +(defun metest-imenu-tlc-files () + "Return list of full paths to each metest-imenu-tlc-files/*.tlc." + (directory-files "metest-imenu-tlc-files" t "\\.tlc$")) + +(defvar metest-imenu-tlc (cons "metest-imenu-tlc" (metest-imenu-tlc-files))) + +(defun metest-imenu-tlc (&optional tlc-file) + "Test MATLAB imenu support using ./metest-imenu-tlc-files/TLC-FILE. +Compare ./metest-imenu-tlc-files/TLC-FILE against +./metest-imenu-tlc-files/NAME_expected.txt, where NAME_expected.txt +contains the matched functions of the tlc--imenu-generic-expression +regexp, one per line. + +If TLC-FILE is not provided, loop comparing all + ./metest-imenu-tlc-files/*.tlc + +For debugging, you can run with a specified TLC-FILE, + M-: (metest-imenu-tlc \"metest-imenu-tlc-files/TLC-FILE\")" + (let* ((tlc-files (if tlc-file + (progn + (setq tlc-file (file-truename tlc-file)) + (when (not (file-exists-p tlc-file)) + (error "File %s does not exist" tlc-file)) + (list tlc-file)) + (metest-imenu-tlc-files)))) + (dolist (tlc-file tlc-files) + (save-excursion + (message "START: (metest-imenu-tlc \"%s\")" tlc-file) + + (find-file tlc-file) + (goto-char (point-min)) + + (let* ((imenu-re (cadar tlc--imenu-generic-expression)) + (got "") + (expected-file (replace-regexp-in-string "\\.tlc$" "_expected.txt" tlc-file)) + (got-file (concat expected-file "~")) + (expected (when (file-exists-p expected-file) + (with-temp-buffer + (insert-file-contents-literally expected-file) + (buffer-string)))) + (case-fold-search nil)) + (while (re-search-forward imenu-re nil t) + (setq got (concat got (match-string 1) "\n"))) + + (when (not (string= got expected)) + (let ((coding-system-for-write 'raw-text-unix)) + (write-region got nil got-file)) + (when (not expected) + (error "Baseline for %s does not exists. See %s and if it looks good rename it to %s" + tlc-file got-file expected-file)) + (error "Baseline for %s does not match, got: %s, expected: %s" + tlc-file got-file expected-file)) + (kill-buffer))) + (message "PASS: (metest-imenu-tlc \"%s\")" tlc-file))) + "success") + +(provide 'metest-imenu-tlc) +;;; metest-imenu-tlc.el ends here diff --git a/tests/metest.el b/tests/metest.el index 04b42f71a3..87e223b840 100644 --- a/tests/metest.el +++ b/tests/metest.el @@ -39,6 +39,7 @@ (require 'metest-font-lock-test2) (require 'metest-indent-test2) (require 'metest-imenu) +(require 'metest-imenu-tlc) (defun metest-all-syntax-tests () "Run all the syntax test cases in this file." @@ -66,6 +67,7 @@ (metest-run 'metest-indents-test) (metest-imenu) + (metest-imenu-tlc) ;; Parsing and completion are high level tools (metest-run 'metest-complete-test) diff --git a/tlc.el b/tlc.el index eecd7d5be8..4ce364fc07 100644 --- a/tlc.el +++ b/tlc.el @@ -137,6 +137,10 @@ :group 'tlc :type 'hook) +(defvar tlc--imenu-generic-expression + '((nil "^[[:blank:]]*%function[[:blank:]]+\\([a-zA-Z0-9_]+\\)" 1)) + "Regexp to find function names in *.tlc files for `imenu'.") + (defvar tlc-syntax-table nil "Syntax table used in an TLC file.") @@ -233,21 +237,19 @@ (setq mode-name "TLC") (use-local-map tlc-mode-map) (set-syntax-table tlc-syntax-table) - (make-local-variable 'comment-start) - (make-local-variable 'comment-end) - (make-local-variable 'comment-start-skip) - (setq comment-start "%% " - comment-end "") - (setq comment-start-skip "%%\\|/%") - (make-local-variable 'indent-line-function) - (setq indent-line-function 'tlc-indent) - (make-local-variable 'font-lock-defaults) - (setq font-lock-defaults '((tlc-font-lock-keywords) + (setq-local comment-start "%% ") + (setq-local comment-end "") + (setq-local comment-start-skip "%%\\|/%") + (setq-local indent-line-function 'tlc-indent) + (setq-local font-lock-defaults '((tlc-font-lock-keywords) nil ; do not do string/comment highlighting nil ; keywords are case sensitive. ;; This puts _ as a word constituent, ;; simplifying our keywords significantly ((?_ . "w")))) + + (setq-local imenu-generic-expression tlc--imenu-generic-expression) + (tlc-version) (save-excursion (goto-char (point-min))