├── .gitignore ├── ChangeLog ├── ChangeLog.old1 ├── ChangeLog.old2 ├── INSTALL ├── Makefile ├── Project.ede ├── README.md ├── cedet-matlab.el ├── company-matlab-shell.el ├── company-matlab.el ├── dl_emacs_support.m ├── flycheck-matlab-mlint.el ├── linemark.el ├── matlab-publish.el ├── matlab.el ├── mlint.el ├── semantic-matlab.el ├── semanticdb-matlab.el ├── srecode-matlab.el ├── templates ├── Makefile ├── Project.ede └── srecode-matlab.srt ├── tlc.el └── toolbox ├── Makefile ├── Project.ede ├── emacsdocomplete.m ├── emacsinit.m └── opentoline.m /.gitignore: -------------------------------------------------------------------------------- 1 | *-compile-script 2 | bugs 3 | *.patch 4 | *.diff 5 | semantic.cache 6 | MISC 7 | *.elc 8 | matlab-load.el 9 | matlab-load.el~ 10 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 2014-11-05 zappo 2 | 3 | * Makefile: (VERSION) Updated. 4 | (all, tags, dist): Add toolbox 5 | (toolbox): New rule 6 | 7 | * Project.ede (:version): Updated 8 | 9 | * templates/Makefile (VERSION): Update to minor rev. 10 | 11 | * toolbox/Makefile: Makefile for toolbox. 12 | 13 | * toolbox/Project.ede: Project file for toolbox. 14 | 15 | * INSTALL (tlc.el): Fix typo. 16 | 17 | * matlab.el (matlab-shell-completion-list): 18 | remove custom call to MCR with call to emacsdocomplete.m in the matlab-emacs toolbox directlry. 19 | 20 | * toolbox/emacsdocomplete.m: 21 | Command for getting completions from MATLAB for matlab-shell. 22 | 23 | 2014-11-05 zappo 24 | 25 | * matlab.el (matlab-shell-completion-list): 26 | remove custom call to MCR with call to emacsdocomplete.m in the matlab-emacs toolbox directlry. 27 | 28 | * toolbox/emacsdocomplete.m: 29 | Command for getting completions from MATLAB for matlab-shell. 30 | 31 | 2014-09-24 zappo 32 | 33 | * .cvsignore: First checkin. 34 | 35 | 2014-09-23 zappo 36 | 37 | * matlab.el (matlab-shell-font-lock-keywords): 38 | Tweak to support some changes in error output. 39 | (matlab-comment): For comment on same line. If we run out of space (fill-column) 40 | pull the comment closer to the code. 41 | (matlab-auto-fill): When filling a string, improve checking of when to add brackets 42 | around the string. 43 | (matlab-shell-mode): Disable html rendering trickery. 44 | (gud-matlab-error-regexp): Add a new variant (off by default) as reminder to 45 | go back and get the current ones to handle newer MATLAB error format. 46 | 47 | 2014-03-07 zappo 48 | 49 | * mlint.el (mlint-minor-mode): Remove make-local-hook for Emacs 24. 50 | 51 | 2013-08-29 zappo 52 | 53 | * semantic-matlab.el (semantic/dep): New dependency (Emacs 24) 54 | (semantic-matlab-parse-oldstyle-class): Add 'method' local var to tidy 55 | compile warnings. 56 | 57 | 2013-08-26 zappo 58 | 59 | * matlab.el (matlab-mode-version): Bump very-minor versin. 60 | (matlab-ltype-comm): Add support for block comment detection. 61 | (matlab-ltype-block-comm): New fcn. 62 | (matlab-shell): Add TAB binding for TAB for when (tab) doesn't work. 63 | Add support for setting WINDOWID environment variable so that MATLAB 64 | will bring Emacs forward when typing in a figure. 65 | 66 | 2013-04-02 zappo 67 | 68 | * README: Update to discuss CEDET that comes with Emacs. 69 | 70 | * INSTALL: Update to note latest build notes. 71 | 72 | * Makefile: Regenerated 73 | Added CEDET_PATH variable if someone wants to download the latest from bzr. 74 | 75 | * Project.ede (:version): Updated 76 | (lisp): Add linemark.el 77 | 78 | * matlab-load.el: Regenerated. 79 | 80 | * dl_emacs_support.m (coreFiles): Add linemark.el to download list. 81 | 82 | * linemark.el: 83 | Add linemark to matlab-emacs dist so that mlint will work 84 | with the version of CEDET integrated with Emacs. 85 | 86 | * cedet-matlab.el (matlab-cedet-setup): 87 | Update srecode require to work w/ CEDET 88 | integrated w/ Emacs. 89 | 90 | * semantic-matlab.el (misc require statements): 91 | Updated to work w/ CEDET integrated w/ Emacs. 92 | 93 | * semanticdb-matlab.el (misc require statements): 94 | Updated to work w/ CEDET integrated w/ Emacs. 95 | (semanticdb-matlab-scan-directories): Remove references to `working'. 96 | (semanticdb-matlab-cache-files): Remove references to `working'. 97 | 98 | * templates/Makefile (VERSION): Updated. 99 | 100 | 2012-02-23 zappo 101 | 102 | * matlab.el (matlab-mode): 103 | Change page-delimeter to allow any whitespace or \n after a %%. 104 | 105 | 2011-10-05 zappo 106 | 107 | * matlab.el (matlab-ltype-endfunction-comm): 108 | If the endfunction comment occurs on 109 | a line, but the next bit of code isn't part of an enclosing fcn, then no. 110 | (matlab-shell-mode): Patch from Eli Merriam; 111 | make comint-input-filter-functions buffer local. 112 | Add matlab-shell-render-html-txt-format hook to comint. 113 | (matlab-txt-format-beg, matlab-txt-format-end): New 114 | (matlab-shell-render-html-txt-format): New. 115 | (matlab-shell-last-anchor-as-frame): New. 116 | (matlab-shell-render-errors-as-anchor): Use last anchor var above. 117 | Note: Not used for any logic yet. ;( 118 | (matlab-shell-previous-matching-input-from-input): patch; Mark Histed 119 | Force cursor to eol. 120 | (matlab-shell-run-region): Force displayed buffer to recycled visible buffers. 121 | 122 | 2011-08-10 davenar 123 | 124 | * matlab.el (matlab-shell-mode): 125 | Add `comint-postoutput-scroll-to-bottom' to 126 | `comint-output-filter-functions' (suggested by Mark Histed). 127 | 128 | 2011-08-09 davenar 129 | 130 | * matlab.el (matlab-shell-run-region): 131 | Fix last commit and correctly use 132 | `buffer-substring' again. 133 | 134 | * matlab.el (matlab-shell-run-region): 135 | When removing comments, do not touch matlab 136 | strings or we might remove format specifiers. 137 | 138 | 2011-07-17 davenar 139 | 140 | * matlab.el (matlab-shell-run-region): 141 | Remove all comments before running a 142 | region, otherwise `matlab-shell-run-cell' will break. 143 | 144 | * matlab.el (matlab-shell-run-region): 145 | Remove comment lines. If NOSHOW, also 146 | remove continuations. 147 | 148 | * matlab.el (matlab-shell-run-region): 149 | New optional argument NOSHOW to replace 150 | newlines with commas, so that by default this will not be done. 151 | (matlab-shell-run-cell): Use it. 152 | 153 | 2011-06-16 zappo 154 | 155 | * matlab.el (matlab-shell-render-html-anchor): 156 | Add arbitrary reverse-search limit 157 | to improve performance when the output buffer gets large. 158 | 159 | 2011-03-23 zappo 160 | 161 | * matlab.el (matlab-shell-use-emacs-toolbox): Fix to use let* 162 | 163 | * matlab.el (matlab-shell-running-matlab-release): 164 | Make more robust if matlab.el 165 | is not on the path. 166 | (matlab-shell-window-exists-for-display-completion-flag): New flag 167 | (matlab-shell-tab): Update to set window exists flag (above) when 168 | showing completions, and call hide-completions (below) when done 169 | completing. 170 | (matlab-shell-tab-hide-completions): New. 171 | 172 | 2010-12-08 zappo 173 | 174 | * matlab.el (matlab-mode): 175 | Move line that moves point to end of buffer to just 176 | in front of where it is used, and inside a save-excursion. 177 | 178 | 2010-12-06 zappo 179 | 180 | * matlab.el: Patch from Rudiger Sonderfeld 181 | (matlab-frame-init): Add a "switch to" in addition to "start" matlab 182 | menu item to make it clear what will happen. 183 | 184 | 2010-10-20 zappo 185 | 186 | * mlint.el (mlint-platform): 187 | Get smarter about returning the kind of MAC and WIN supported. 188 | (mlint-minor-mode): Don't disable verify on save since there is still useful stuff there. 189 | 190 | 2010-10-14 zappo 191 | 192 | * dl_emacs_support.m: Patch from: Joe Vornehm 193 | (coreFiles): Add matlab-publish.el and company-matlab-shell.el 194 | (mktemplatedir,mktoolboxdir): Pay attention to destination argument. 195 | 196 | 2010-09-14 zappo 197 | 198 | * matlab.el (matlab-mode): 199 | Wrap guessing of indentation in a save-excursion. 200 | and running of hooks in a save excursion so point can be moved during 201 | checking for the indentation style. 202 | (matlab-toggle-show-mlint-warnings) 203 | (matlab-toggle-highlight-cross-function-variables): 204 | Always call mlint-minor-mode after a change, but pass in a numeric arg 205 | to force on or off dependent on the current state. 206 | 207 | 2010-07-29 zappo 208 | 209 | * mlint.el (mlint-run): Fix case where mlint-program was buffer local. 210 | 211 | 2010-07-28 zappo 212 | 213 | * matlab.el (gud-matlab-error-regexp): 214 | Patch from EricW: Fix for more error types. 215 | (matlab-shell-run-region): Add hack for replacing CR w/ ,. 216 | (matlab-shell-last-error): Fix call to find other window call so 0 is a str. 217 | 218 | * mlint.el (mlint-program-selection-fcn): New option. 219 | (mlint-minor-mode): Use above to select an mlint program. 220 | 221 | 2010-04-06 zappo 222 | 223 | * matlab.el (matlab-shell-html-map): Update how it is initialized. 224 | Add binding for return 225 | (matlab-anchor-beg): Add to expression to remove "matlab:" 226 | (matlab-shell-render-html-anchor): Add help-echo. 227 | (gud-matlab-error-regexp): Improve for newere MATLABs 228 | (matlab-shell-last-error-anchor): New 229 | (matlab-shell-render-errors-as-anchor): No longer depend on deleted 230 | stack start/end variables which seem to no longer be active. 231 | Add help-echo to overlay. 232 | Change how 'first' is calculated, apply after the fact. 233 | (gud-matlab-marker-filter):Don't collect if prompt hasn't been seen yet. 234 | (matlab-shell-html-click): Now use below 235 | (matlab-shell-html-go): New from above. 236 | 237 | 2010-01-21 zappo 238 | 239 | * INSTALL: Fix path to not say "matlab.el" 240 | 241 | 2010-01-13 zappo 242 | 243 | * matlab.el (gud-matlab-marker-filter): Don't filter out backspace. 244 | In section collecting whole error strings, wait for \n, not the prompt. 245 | 246 | 2010-01-05 zappo 247 | 248 | * matlab.el (matlab-mode-version): Update minor version number. 249 | (matlab-indent-function-body): Add 'MathWorks-Standard option. 250 | (matlab-functions-have-end-minor-mode): Add code to flip the 251 | `matlab-functions-have-end' variable. 252 | (matlab-do-functions-have-end-p): New. 253 | (matlab-indent-function-body-p): New function. 254 | (matlab-mode): First detect if fcns have end, save. 255 | Next detect indenting fcn bodies based on 'guess. 256 | (matlab-calculate-indentation-1, matlab-next-line-indentation) 257 | (matlab-frame-init): 258 | Use fcn form of indent-function-body. 259 | 260 | 2009-12-23 zappo 261 | 262 | * INSTALL: Fix typo about augmenting the load path. 263 | 264 | 2009-11-16 zappo 265 | 266 | * semanticdb-matlab.el (semanticdb-matlab-include-paths): 267 | Only set default to ~/matlab if it exists. 268 | 269 | 2009-09-23 zappo 270 | 271 | * matlab.el (matlab-shell-tab): 272 | Add '.' to list of chars that limit completion. 273 | This enables structure completion. 274 | 275 | 2009-09-15 zappo 276 | 277 | * README: Change load-path setup line. 278 | 279 | 2009-09-03 zappo 280 | 281 | * matlab.el (matlab-shell-mode): 282 | Add debugging next, and fix step to step in. 283 | 284 | * matlab.el (gud-matlab-marker-filter): Remove debug message. 285 | 286 | * matlab.el (matlab-shell-mode): 287 | Add matlab-shell-render-errors-as-anchor to 288 | comint-output-filter-functions. 289 | (matlab-anchor-beg,matlab-anchor-end) 290 | (gud-matlab-marker-regexp-1,gud-matlab-marker-regexp-2): Moved. 291 | (gud-matlab-marker-regexp-prefix): Updated. 292 | (gud-matlab-error-regexp): Updated. 293 | (matlab-last-frame-returned): Deleted. 294 | (gud-matlab-error-regexp): Updated. 295 | (matlab-shell-render-html-anchor): Remove debugger jumping code. 296 | (matlab-shell-error-stack-start, matlab-shell-error-stack-end): New 297 | (matlab-shell-render-errors-as-anchor): New. 298 | (gud-matlab-marker-filter): Remove support for MATLAB 5 debugging. 299 | I don't think it would have worked anyway. (matlab-one-db-request stuff). 300 | For frame calculations, query out of gud-marker-acc instead of scanning the buffer 301 | which was unreliable. 302 | When stripping individual lines from the return buffer, only do so if 303 | there is no telltale sign of debugger output. 304 | (matlab-url-stack-top-at): New. 305 | (matlab-shell-previus-matlab-url):Call above is new arg is t. 306 | (matlab-find-other-window-file-line-column): Be robust to more types 307 | of file names that might not have .m on the end. 308 | (matlab-shell-last-error): Specify there might be a stack, and choose the top. 309 | 310 | 2009-08-21 zappo 311 | 312 | * matlab-load.el: Regenerated. 313 | 314 | * mlint.el (mlint-minor-mode): Add autoload cookie. 315 | 316 | * matlab.el (mline): Remove require. 317 | (matlab-functions-have-end-minor-mode): Remove bogus doc string (copy paste bug). 318 | 319 | * dl_emacs_support.m: Add toolbox M files, and toolbox constructor. 320 | 321 | 2009-08-13 zappo 322 | 323 | * matlab.el (mlint): Add require. 324 | (defcustom, etc): Delete old backward compatable stuff for Emacs 19. 325 | (matlab-toggle-functions-have-end-minor-mode): Moved to supress 326 | byte compile warnings. 327 | (matlab-font-lock-nested-function-keyword-match) 328 | (matlab-font-lock-cross-function-variables-match): Make overlay a local variable. 329 | (matlab-mode): Comments about byte-comp warnings. 330 | (gud-matlab-marker-filter,matlab-find-other-window-file-line-column): 331 | Use string-to-number. 332 | (matlab-shell-run-region-or-line): New new mechanism w/ transient-mark-mode. 333 | (matlab-shell-topic-highlight-line): Add comment. 334 | 335 | * matlab.el: Misc: Add (R) to some occurances of MATLAB. 336 | OBSOLETE STUFF: 337 | (matlab-hilit19-patterns,fume-function-name-regexp-matlab) 338 | (fume-find-next-matlab-function-name,matlab-mode-hilit): Delete 339 | (matlab-imenu-generic-expression): Get rid of fume use. 340 | INDENT FIX: 341 | (matlab-valid-end-construct-p,matlab-lattr-block-close) 342 | (matlab-calc-indent,matlab-calculate-indentation) 343 | (matlab-calculate-indentation-1): Handle multiple ends on one line. 344 | MATLAB EDITOR UPDATE: 345 | (matlab-shell-history-file): Calculate from below. 346 | (matlab-shell-running-matlab-version, matlab-shell-running-matlab-release) 347 | (matlab-shell-use-emacs-toolbox, matlab-shell-emacsclient-command): 348 | New variables. 349 | (matlab-shell,matlab-shell-hack-logo,matlab-shell-mode) 350 | (gud-matlab-marker-filter): 351 | Calc version from output. 352 | (matlab-shell-version-scrape): New, for above. 353 | (matlab-shell-next-matching-input-from-input) 354 | (matlab-shell-prev-matching-input-from-input): New commands. 355 | (matlab-find-other-window-via-url): Support opentoline links. 356 | 357 | * toolbox/emacsinit.m, toolbox/opentoline.m: 358 | Support calling Emacs from MATLAB via edit commands. 359 | 360 | 2009-07-07 zappo 361 | 362 | * INSTALL: Fix LOADPATH discussion. 363 | 364 | * matlab-load.el: Rebuild using Emacs 23. 365 | Adds a provide statement. 366 | 367 | 2009-07-07 davenar 368 | 369 | * ChangeLog, semanticdb-matlab.el (semanticdb-matlab-scan-directories): 370 | Local bind for working-spinner-display. 371 | 372 | 2009-07-07 David Engster 373 | 374 | * semanticdb-matlab.el (semanticdb-matlab-scan-directories): Local 375 | bind for working-spinner-display. 376 | 377 | 2009-07-06 Eric Ludlam 378 | 379 | * company-matlab-shell.el: Company mode support for matlab-shell. 380 | 381 | * README: Added notes on CEDET use. 382 | Added notes on on the MATLAB download script. 383 | 384 | * matlab.el (matlab-mode-version): Update. 385 | 386 | * matlab-publish.el: Utilities for editing MATLAB files for publishing 387 | 388 | * templates/srecode-matlab.srt: SRecode templates for MATLAB Script. 389 | 390 | * semantic-matlab.el: Remove automatic init hook. See cedet-matlab.el 391 | 392 | * cedet-matlab.el: Initialization support for CEDET tools with MATLAB. 393 | 394 | * dl_emacs_support.m: Convenience download script. 395 | 396 | * matlab.el (matlab-indent-function-body): 397 | Allow a value of 'guess, meaning 398 | to guess the indentation style of a pre-existing file. 399 | (matlab-keyword-list,matlab-font-lock-keywords) 400 | (matlab-block-beg-pre-if,matlab-block-beg-pre-no-if) 401 | (matlab-keywords-solo,matlab-quiesce-nosemi-regexp): 402 | Add spmd. 403 | 404 | 2008-10-17 Eric Ludlam 405 | 406 | * matlab.el: Add enumeration support. 407 | 408 | 2008-09-18 David Engster 409 | 410 | * semanticdb-matlab.el (semanticdb-find-tags-by-name-method): 411 | Use our own database as 412 | fall-back method. 413 | (semanticdb-find-tags-for-completion-method): Combine results from 414 | MATLAB shell and our own database. 415 | 416 | 2008-09-08 David Engster 417 | 418 | * semantic-matlab.el: (semantic-ctxt-current-symbol) 419 | (semantic-ctxt-current-symbol-and-bounds): Return nil when no symbol 420 | at point. 421 | 422 | * semantic-matlab.el (semantic-matlab-parse-assignments): 423 | Deal with class methods which 424 | return same class and be more tolerant with whitespaces. 425 | 426 | * semantic-matlab.el (semantic-matlab-parse-assignments): 427 | Fix bug in parsing limit. Don't parse 428 | current line. Deal with class attribute assignments. 429 | 430 | 2008-09-07 David Engster 431 | 432 | * semanticdb-matlab.el (semanticdb-matlab-user-class-cache): 433 | New variable. 434 | (semanticdb-matlab-cache-files): New function for caching files and 435 | classes. 436 | (semanticdb-matlab-find-name): Use it. 437 | (semantic-ctxt-current-class-list): Deal with classes and structures. 438 | 439 | * semantic-matlab.el: (semantic-matlab-parse-oldstyle-class) 440 | (semantic-matlab-find-oldstyle-classes): New functions. 441 | (semantic-matlab-parse-region): Cache files. Use new functions for 442 | parsing classes. 443 | (semantic-matlab-type-hint-string): New variable. 444 | (semantic-matlab-parse-assignments): New function. 445 | (semantic-get-local-variables): New override. 446 | (semantic-ia-insert-tag): Deal with method completions. 447 | (semantic-ctxt-current-symbol) 448 | (semantic-ctxt-current-symbol-and-bounds): New overrides. 449 | 450 | * semantic-matlab.el (semantic-matlab-root-directory): Follow symlink. 451 | 452 | 2008-09-05 Eric Ludlam 453 | 454 | * semanticdb-matlab.el (semanticdb-find-tags-by-name-method): 455 | Fixed to handle case where 456 | matlab lies about the doc file location. 457 | (semanticdb-find-tags-for-completion-method): Adapt to use 458 | matlab-shell when available. 459 | 460 | * semanticdb-matlab.el (semanticdb-find-tags-by-name-method): 461 | Use matlab-shell if available. 462 | 463 | * semantic-matlab.el (semantic-matlab-root-directory): New Function. 464 | (semantic-matlab-function-tags): Update to use above. 465 | 466 | * matlab.el (matlab-shell-which-fcn): Append .m to builtin. 467 | (matlab-shell-matlabroot): New 468 | (matlab-shell-collect-command-output): Stop displaying status messages. 469 | 470 | * matlab.el: (matlab-shell-completion-list): 471 | Enabled to work in a non-shell buffer by switching over. 472 | (matlab-shell-which-fcn): New. 473 | 474 | * INSTALL: 475 | Revies to new matlab-load.el style. Discuss use w/out the Makefile. 476 | Remove semantic-matlab.el doc, it needs a re-write. 477 | 478 | * Makefile (LOADPATH): Add semantic/bovine 479 | 480 | * Project.ede (cedet): Add semantic-el dependency. 481 | 482 | * Makefile (LOADPATH): Now includes semantic. 483 | (cedet_LISP): New veriables. 484 | (cedet): New target. 485 | (dist): Add the cedet support files. 486 | 487 | * Project.ede ("lisp"): Added versionsource file. 488 | ("semantic"): New target 489 | 490 | * matlab.el (matlab-vers-on-startup): Set default to off. 491 | (auto-mode-alist): Add .m files. 492 | (matlab-block-end-pre-no-iff): Fix if/else order typo. 493 | 494 | * README: Update to latest information on installing matlab.el 495 | 496 | 2008-09-02 Eric Ludlam 497 | 498 | * mlint.el (mlint-platform): 499 | Use string-match to determine 64 bit linux-ness. 500 | (mlint-flags): Remove -fix until I get around to supporting it. 501 | 502 | 2008-09-01 David Engster 503 | 504 | * semanticdb-matlab.el: Fix doc-strings. 505 | 506 | * semantic-matlab.el (semantic-idle-summary-function): 507 | Use defvar-mode-local instead of 508 | make-local-variable. 509 | 510 | 2008-08-31 David Engster 511 | 512 | * semantic-matlab.el (semantic-format-tag-prototype): 513 | New overload for matlab-mode. 514 | (semantic-idle-summary-format-matlab-mode): New function, also 515 | displays doc-string. 516 | (semantic-ia-insert-tag): Use it. 517 | (semantic-default-matlab-setup): Bind `semantic-idle-summary-function'. 518 | 519 | * semantic-matlab.el: Unconditional require of semanticdb-matlab. 520 | (semantic-matlab-function-tags): Better parsing of doc strings. 521 | Return flag for builtin functions. 522 | (semantic-matlab-sort-raw-tags): Include new :builtin attribute. 523 | 524 | 2008-08-30 David Engster 525 | 526 | * INSTALL: Added section for semantic-matlab.el 527 | 528 | * semantic-matlab.el (semantic-matlab-system-paths-include): 529 | New variable. 530 | (semantic-matlab-dependency-system-include-path): Use it. 531 | (semantic-matlab-root-directory): Take everything until '/bin' as 532 | MATLAB root. 533 | 534 | * semanticdb-matlab.el: 535 | New file. Semantic database extensions for MATLAB. 536 | 537 | 2008-08-22 Eric Ludlam 538 | 539 | * semantic-matlab.el (semantic-matlab-dependency-system-include-path): 540 | Value should be a list. 541 | 542 | * semantic-matlab.el: Changes contributed by: David Engster 543 | (semanticdb-matlab): Conditional load. 544 | (semeantic-matlb-root-directory): New variable 545 | (semantic-matlab-match-function-re): Support _ 546 | (semantic-matlab-function-tags): Support loading doc strings. 547 | (semantic-matlab-sort-raw-tags): Support doc strings. 548 | (semantic-matlab-dependency-system-include-path) 549 | (semantic-matlab-display-docstring): New variables 550 | (semantic-ia-insert-tag): New overload function. 551 | 552 | 2008-08-05 Eric Ludlam 553 | 554 | * matlab.el (matlab-shell-ask-MATLAB-for-completions): 555 | Change default to t. 556 | Patch from David Engster: 557 | (matlab-shell-completion-list): Set scroll-show-maximum-output to nil. 558 | (matlab-shell-tab): Improve completion list extraction. 559 | 560 | 2008-08-01 Eric Ludlam 561 | 562 | * mlint.el (mlint-symtab-info): New variable. 563 | (mlint-run): Init symtab local var. 564 | Fixed symbol table parsing to work with newer mlint. 565 | 566 | * matlab.el (matlab-block-indent-toc-toc-flag): 567 | New variable. Default nil. 568 | (matlab-block-beg-pre-if, matlab-block-beg-pre-no-if) 569 | (matlab-block-end-pre-if, matlab-block-end-pre-no-if): 570 | If the tic-toc flag is nil, don't indent tic/tocs. 571 | 572 | 2008-05-19 Eric Ludlam 573 | 574 | * semantic-matlab.el: Copied from cedet repository. 575 | 576 | * matlab.el (matlab-keyword-list): Add mcos keywords 577 | (matlab-defun-regex, matlab-block-beg-pre-if, matlab-block-beg-pre-no-if): 578 | Updated w/ mcos keywords. 579 | 580 | * mlint.el (mlint-calculate-cyclic-complexity-flag): New flag. 581 | (mlint-flags): Add -fix 582 | (mlint-run): Use cyclic-complexity flag. 583 | 584 | * matlab.el (matlab-mode-version): Update 585 | (matlab-cellbreak-face): Fancy new face for cell-breaks. 586 | (matlab-font-lock-adjustments): Update cellbreak face. 587 | (matlab-font-lock-keywords): Add cellbreak highlighting. 588 | (matlab-mode): Fix spelling in indent-sexp keybinding to doc. 589 | 590 | 2007-03-06 Eric Ludlam 591 | 592 | * mlint.el: 593 | (mlint-clear-warnings, mlint-clear-cross-function-variable-highlighting): 594 | Make font-lock optional. 595 | 596 | 2007-01-08 Eric Ludlam 597 | 598 | * matlab.el: (matlab-block-end-pre-if, matlab-block-end-pre-no-if): 599 | Support assigning toc into a subs-assign. (Thanks Jim Van Zant) 600 | 601 | 2006-10-04 Eric Ludlam 602 | 603 | * mlint.el (mlint-output-regex): 604 | Support the changed mlint output syntax 605 | (mlint-symtab-line-regexp): Support changed mlint table output syntax 606 | (mlint-warning-code-alist): Obsolete 607 | (mlint-error-fix-alist): Obsolete 608 | (mlint-error-id-fix-alist): New version of the old error-fix-alist. 609 | (mlint-run): Add the "-edit" flag when highlighting crossfunction variables. 610 | Updated parsing of the mlint table for highlighting cross-function variables. 611 | Updated mechanism for highlighting the cross-function variables. 612 | (mlint-lm-entry): Update warningid doc. 613 | (mlint-warning->class, mlint-warningid->class): Name change. Use new table of warning ids 614 | instead of parsing warning strings. 615 | (linemark-new-entry): Use warning id, not warning string for class determination. 616 | (mlint-lm-replace-focus): new-text is no longer class allocated. 617 | (mlint-lm-entry-depricated): New class rule. 618 | (mlint-lm-entry-isstr, mlint-lm-entry-setstr): Deleted. 619 | (mlint-lm-eval->trycatch): Commented out. Not provided by mlint, but it 620 | is cool and could be resurrected. 621 | (mlint-highlight): Can't provide warningcode anymore. 622 | (mlint-clear-cross-function-variable-overlays): Renamed to 623 | (mlint-clear-nested-function-info-overlays): updated w/ more info. 624 | (mlint-clear-cross-function-variable-highlighting) 625 | (mlint-minor-mode): Use new clear function for nested function info. 626 | 627 | * matlab.el: Make fill-paragraph work around cell headings nicely. 628 | Add `matlab-shell-run-cell' for cell-mode style execution of code. 629 | Change the page delimiter to include cell breaks. 630 | 631 | Support "parfor", available in MATLAB 2006a. 632 | Treat cell start comments as the start of a comment block, even if comments preceed it. 633 | Make sure typing in comment chars moves cursor to the correct location. 634 | 635 | 2005-12-02 Eric Ludlam 636 | 637 | * ChangeLog: Build and dependancies changes. 638 | 639 | * INSTALL, README: Add info about CEDET dependancies. 640 | 641 | * Makefile, Project.ede, matlab-load.el: Build system. 642 | 643 | 2005-12-02 Eric Ludlam 644 | 645 | * README, INSTALL: Refer to CEDET project for dependancies. 646 | 647 | * Makefile, Project.ede: New build system. 648 | 649 | * matlab-load.el: autoloads file. 650 | 651 | 2005-12-01 Eric Ludlam 652 | 653 | * matlab.el: Removed ChangLog from end of file. 654 | 655 | -------------------------------------------------------------------------------- /ChangeLog.old2: -------------------------------------------------------------------------------- 1 | This is the old ChangeLog from CVS @ MathWorks via checkin comments. 2 | 3 | --------------- 4 | 5 | ;;; $Log$ 6 | Revision 1.4.4.11.2.4.2.2 2005/11/16 13:53:36 eludlam 7 | Small completion patch. 8 | 9 | Revision 1.4.4.11.2.4.2.1 2005/11/16 13:52:20 eludlam 10 | Small completion patch. 11 | 12 | Revision 1.4.4.11.2.4 2005/07/11 20:14:13 batserve 13 | 2005/06/27 1.4.4.14 batserve 14 | 2005/06/21 1.4.4.13.2.1 padman 15 | Saved after merging from 1.4.8.2 (Akernel) to dev_padman_A (1.4.4.13.2.0) 16 | 2005/06/21 1.4.4.13.2.2 padman 17 | Code Reviewer: TBRB mkarr,eludlam,csiegal 18 | merged Akernel,A versions 19 | some of Akernel's changes already got into A 20 | please review the merges 21 | Accepted job 28303 in A 22 | Accepted job 15746a in Ami 23 | Revision 1.4.4.11.2.5 2005/09/20 04:53:59 batserve 24 | 2005/09/08 1.4.4.15 batserve 25 | 2005/08/01 1.4.10.1 batserve 26 | 2005/07/29 1.4.4.14.6.1 mkarr 27 | Related Records: 274559 28 | Code Reviewer: Eric Ludlam 29 | Introduced functions-have-end minor mode. 30 | Introduced special highlighting for nested function/end. 31 | Optimize matlab-backward-sexp by assuming that sexps to not cross 32 | "function" at the left margin. 33 | Handle documentation anchors (links). 34 | Fixed a bug in highlighting cross-function variables. 35 | Fixed infinite loop bug when matching "end" to "function", 36 | in the mode where functions are not expected to have "end". 37 | Accepted job 2313 in Alead 38 | Accepted job 28899 in A 39 | Accepted job 16896b in Ami 40 | 41 | Revision 1.4.4.15 2005/09/08 20:31:39 batserve 42 | 2005/08/01 1.4.10.1 batserve 43 | 2005/07/29 1.4.4.14.6.1 mkarr 44 | Related Records: 274559 45 | Code Reviewer: Eric Ludlam 46 | Introduced functions-have-end minor mode. 47 | Introduced special highlighting for nested function/end. 48 | Optimize matlab-backward-sexp by assuming that sexps to not cross 49 | "function" at the left margin. 50 | Handle documentation anchors (links). 51 | Fixed a bug in highlighting cross-function variables. 52 | Fixed infinite loop bug when matching "end" to "function", 53 | in the mode where functions are not expected to have "end". 54 | Accepted job 2313 in Alead 55 | Accepted job 28899 in A 56 | 57 | Revision 1.4.10.1 2005/08/01 15:13:19 batserve 58 | 2005/07/29 1.4.4.14.6.1 mkarr 59 | Related Records: 274559 60 | Code Reviewer: Eric Ludlam 61 | Introduced functions-have-end minor mode. 62 | Introduced special highlighting for nested function/end. 63 | Optimize matlab-backward-sexp by assuming that sexps to not cross 64 | "function" at the left margin. 65 | Handle documentation anchors (links). 66 | Fixed a bug in highlighting cross-function variables. 67 | Fixed infinite loop bug when matching "end" to "function", 68 | in the mode where functions are not expected to have "end". 69 | Accepted job 2313 in Alead 70 | 71 | Revision 1.4.4.14.6.1 2005/07/29 19:50:48 mkarr 72 | Related Records: 274559 73 | Code Reviewer: Eric Ludlam 74 | 75 | Introduced functions-have-end minor mode. 76 | Introduced special highlighting for nested function/end. 77 | Optimize matlab-backward-sexp by assuming that sexps to not cross 78 | "function" at the left margin. 79 | Handle documentation anchors (links). 80 | Fixed a bug in highlighting cross-function variables. 81 | Fixed infinite loop bug when matching "end" to "function", 82 | in the mode where functions are not expected to have "end". 83 | Revision 1.4.4.11.2.5 2005/09/20 04:53:59 batserve 84 | 2005/09/08 1.4.4.15 batserve 85 | 2005/08/01 1.4.10.1 batserve 86 | 2005/07/29 1.4.4.14.6.1 mkarr 87 | Related Records: 274559 88 | Code Reviewer: Eric Ludlam 89 | Introduced functions-have-end minor mode. 90 | Introduced special highlighting for nested function/end. 91 | Optimize matlab-backward-sexp by assuming that sexps to not cross 92 | "function" at the left margin. 93 | Handle documentation anchors (links). 94 | Fixed a bug in highlighting cross-function variables. 95 | Fixed infinite loop bug when matching "end" to "function", 96 | in the mode where functions are not expected to have "end". 97 | Accepted job 2313 in Alead 98 | Accepted job 28899 in A 99 | Accepted job 16896b in Ami 100 | 101 | Revision 1.4.4.15 2005/09/08 20:31:39 batserve 102 | 2005/08/01 1.4.10.1 batserve 103 | 2005/07/29 1.4.4.14.6.1 mkarr 104 | Related Records: 274559 105 | Code Reviewer: Eric Ludlam 106 | Introduced functions-have-end minor mode. 107 | Introduced special highlighting for nested function/end. 108 | Optimize matlab-backward-sexp by assuming that sexps to not cross 109 | "function" at the left margin. 110 | Handle documentation anchors (links). 111 | Fixed a bug in highlighting cross-function variables. 112 | Fixed infinite loop bug when matching "end" to "function", 113 | in the mode where functions are not expected to have "end". 114 | Accepted job 2313 in Alead 115 | Accepted job 28899 in A 116 | 117 | Revision 1.4.10.1 2005/08/01 15:13:19 batserve 118 | 2005/07/29 1.4.4.14.6.1 mkarr 119 | Related Records: 274559 120 | Code Reviewer: Eric Ludlam 121 | Introduced functions-have-end minor mode. 122 | Introduced special highlighting for nested function/end. 123 | Optimize matlab-backward-sexp by assuming that sexps to not cross 124 | "function" at the left margin. 125 | Handle documentation anchors (links). 126 | Fixed a bug in highlighting cross-function variables. 127 | Fixed infinite loop bug when matching "end" to "function", 128 | in the mode where functions are not expected to have "end". 129 | Accepted job 2313 in Alead 130 | 131 | Revision 1.4.4.14.6.1 2005/07/29 19:50:48 mkarr 132 | Related Records: 274559 133 | Code Reviewer: Eric Ludlam 134 | 135 | Introduced functions-have-end minor mode. 136 | Introduced special highlighting for nested function/end. 137 | Optimize matlab-backward-sexp by assuming that sexps to not cross 138 | "function" at the left margin. 139 | Handle documentation anchors (links). 140 | Fixed a bug in highlighting cross-function variables. 141 | Fixed infinite loop bug when matching "end" to "function", 142 | in the mode where functions are not expected to have "end". 143 | 144 | Revision 1.4.4.14 2005/06/27 20:27:59 batserve 145 | 2005/06/21 1.4.4.13.2.1 padman 146 | Saved after merging from 1.4.8.2 (Akernel) to dev_padman_A (1.4.4.13.2.0) 147 | 2005/06/21 1.4.4.13.2.2 padman 148 | Code Reviewer: TBRB mkarr,eludlam,csiegal 149 | merged Akernel,A versions 150 | some of Akernel's changes already got into A 151 | please review the merges 152 | Accepted job 28303 in A 153 | 154 | Revision 1.4.4.13.2.2 2005/06/21 22:38:35 padman 155 | Code Reviewer: TBRB mkarr,eludlam,csiegal 156 | merged Akernel,A versions 157 | some of Akernel's changes already got into A 158 | please review the merges 159 | 160 | Revision 1.4.4.13.2.1 2005/06/21 22:21:29 padman 161 | Saved after merging from 1.4.8.2 (Akernel) to dev_padman_A (1.4.4.13.2.0) 162 | 163 | Revision 1.4.4.13 2005/06/21 18:51:17 batserve 164 | 2005/05/25 1.4.4.11.2.2 batserve 165 | 2005/01/21 1.4.2.12.2.2 eludlam 166 | Update copyright 167 | 2005/05/17 1.4.2.12.2.3 eludlam 168 | tic/toc indent fix. User fix for auto-fill. 169 | 2005/05/24 1.4.2.12.2.4 eludlam 170 | Related Records: 257613 258664 171 | Code Reviewer: mkarr 172 | Fix indentation numbers. 173 | Fix tic/toc indentation w/ assignments. 174 | Integrate user patch for auto-fill of of strings. 175 | Accepted job 15048 in Ami 176 | 2005/06/04 1.4.4.11.2.3 batserve 177 | 2005/06/02 1.4.2.12.2.5 eludlam 178 | Related Records: 266250 179 | Code Reviewer: mkarr 180 | Allow H1 lines for nested functions to indent correctly. 181 | Make comment char insertion electric. 182 | Added a few completion words. 183 | Fixed byte compilation warnings. 184 | Accepted job 15385 in Ami 185 | Accepted job 28180 in A 186 | 187 | Revision 1.4.4.11.2.3 2005/06/04 23:41:36 batserve 188 | 2005/06/02 1.4.2.12.2.5 eludlam 189 | Related Records: 266250 190 | Code Reviewer: mkarr 191 | Allow H1 lines for nested functions to indent correctly. 192 | Make comment char insertion electric. 193 | Added a few completion words. 194 | Fixed byte compilation warnings. 195 | Accepted job 15385 in Ami 196 | 197 | Revision 1.4.2.12.2.5 2005/06/02 18:44:30 eludlam 198 | Related Records: 266250 199 | Code Reviewer: mkarr 200 | Allow H1 lines for nested functions to indent correctly. 201 | Make comment char insertion electric. 202 | Added a few completion words. 203 | Fixed byte compilation warnings. 204 | 205 | Revision 1.4.2.12.2.4 2005/05/24 18:26:06 eludlam 206 | Related Records: 257613 258664 207 | Code Reviewer: mkarr 208 | Fix indentation numbers. 209 | Fix tic/toc indentation w/ assignments. 210 | Integrate user patch for auto-fill of of strings. 211 | 212 | Revision 1.4.2.12.2.3 2005/05/17 14:59:06 eludlam 213 | tic/toc indent fix. User fix for auto-fill. 214 | 215 | Revision 1.4.2.12.2.2 2005/01/21 21:32:24 eludlam 216 | Update copyright 217 | 218 | Revision 1.4.2.12.2.1 2005/01/21 13:25:11 eludlam 219 | Related Records: 250151 220 | Code Reviewer: paulk 221 | Fix mlint dependency problem. 222 | Fix XEmacs compatibility problem. 223 | Add (behind option) experimental shell completion system. 224 | Add (behind comment) hideshow support. 225 | 226 | Revision 1.4.2.12 2004/06/16 03:10:04 batserve 227 | 2004/06/10 1.4.2.11.2.1 mkarr 228 | Related Records: 168455 229 | Code Reviewer: Ty Lightner, Eric Ludlam 230 | Changes to support nested functions. 231 | Accepted job 12607 in Amisc 232 | 233 | Revision 1.4.2.11.2.1 2004/06/10 13:47:15 mkarr 234 | Related Records: 168455 235 | Code Reviewer: Ty Lightner, Eric Ludlam 236 | 237 | Changes to support nested functions. 238 | 239 | Revision 1.4.2.11 2004/05/13 02:52:11 batserve 240 | 2004/03/11 1.4.6.12 eludlam 241 | Saved after merging with Amisc (1.4.2.9) 242 | 2004/03/19 1.4.6.13 eludlam 243 | Related Records: 210470 244 | Code Reviewer: Various 245 | Fix header comments. 246 | Fix XEmacs compatibility itimer start. 247 | Fix XEmacs overlay compatibility macros. 248 | Add if(false) next to if(0) special code. 249 | Add support for %{ %} block comments. 250 | Fix problem with Emacs Link when not in use, and add new config item. 251 | Add optional feature for automatically adding a semicolon when needed. 252 | Add variable for lines that don't need semicolons. 253 | Fix menu item for mlint to not require it. 254 | Add -nodesktop to the command line switches. 255 | Fix debugger overlay arrow. 256 | Add `matlab-shell-run-region-or-line' command. 257 | 2004/03/19 1.4.6.14 eludlam 258 | Saved after merging with Amisc (1.4.2.10) 259 | Accepted job 12462 in Amisc 260 | 261 | Revision 1.4.6.14 2004/03/19 21:02:02 eludlam 262 | Saved after merging with Amisc (1.4.2.10) 263 | 264 | Revision 1.4.6.13 2004/03/19 20:59:56 eludlam 265 | Related Records: 210470 266 | Code Reviewer: Various 267 | Fix header comments. 268 | Fix XEmacs compatibility itimer start. 269 | Fix XEmacs overlay compatibility macros. 270 | Add if(false) next to if(0) special code. 271 | Add support for %{ %} block comments. 272 | Fix problem with Emacs Link when not in use, and add new config item. 273 | Add optional feature for automatically adding a semicolon when needed. 274 | Add variable for lines that don't need semicolons. 275 | Fix menu item for mlint to not require it. 276 | Add -nodesktop to the command line switches. 277 | Fix debugger overlay arrow. 278 | Add `matlab-shell-run-region-or-line' command. 279 | 280 | Revision 1.4.6.12 2004/03/11 13:42:54 eludlam 281 | Saved after merging with Amisc (1.4.2.9) 282 | 283 | Revision 1.4.6.11 2004/03/10 18:40:26 eludlam 284 | Related Records: 208705 285 | Code Reviewer: ciolfi 286 | Version number change to 2.3.2 287 | Fix comment for installatin. 288 | Fix matlab-end-of-command (patch from user.) 289 | Add mlint enable/disable to matlab menu. 290 | 291 | Revision 1.4.6.10 2003/07/15 16:49:31 eludlam 292 | Version number change. 293 | Added continue to keyword list. 294 | Added use contributed matlab-generate-latex command. 295 | Revision 1.4.2.9 2004/01/30 22:44:48 batserve 296 | 2004/01/28 1.4.4.9 batserve 297 | 2004/01/23 1.4.8.1 batserve 298 | 2004/01/13 1.4.2.8.2.1 mkarr 299 | Code Reviewer: elijah 300 | merged in changes 301 | 2004/01/20 1.4.2.8.2.2 mkarr 302 | Code Reviewer: Eric Ludlam 303 | Make filter buffer-local. 304 | Put in html "rendering" and other changes for 305 | new handling of source locations. 306 | 2004/01/22 1.4.2.8.2.3 mkarr 307 | Code Reviewer: Eric Ludlam 308 | Adapt to column positions in matlab-url. 309 | Accepted job 7543 in Akernel 310 | Accepted job 13127 in A 311 | Accepted job 11551 in Amisc 312 | Revision 1.4.2.10 2004/03/18 21:17:17 batserve 313 | 2004/03/14 1.4.4.10 batserve 314 | 2004/03/10 1.4.4.9.2.1 padman 315 | Saved after merging with 1.4.6.11 (dev_eludlam) 316 | Accepted job 14370 in A 317 | Accepted job 11967a in Amisc 318 | 319 | Revision 1.4.4.10 2004/03/14 15:30:34 batserve 320 | 2004/03/10 1.4.4.9.2.1 padman 321 | Saved after merging with 1.4.6.11 (dev_eludlam) 322 | Accepted job 14370 in A 323 | 324 | Revision 1.4.4.9.2.1 2004/03/10 20:30:27 padman 325 | Saved after merging with 1.4.6.11 (dev_eludlam) 326 | 327 | Revision 1.4.4.9 2004/01/28 23:06:13 batserve 328 | 2004/01/23 1.4.8.1 batserve 329 | 2004/01/13 1.4.2.8.2.1 mkarr 330 | Code Reviewer: elijah 331 | merged in changes 332 | 2004/01/20 1.4.2.8.2.2 mkarr 333 | Code Reviewer: Eric Ludlam 334 | Make filter buffer-local. 335 | Put in html "rendering" and other changes for 336 | new handling of source locations. 337 | 2004/01/22 1.4.2.8.2.3 mkarr 338 | Code Reviewer: Eric Ludlam 339 | Adapt to column positions in matlab-url. 340 | Accepted job 7543 in Akernel 341 | Accepted job 13127 in A 342 | 343 | Revision 1.4.8.2 2005/05/18 19:25:28 batserve 344 | 2005/05/02 1.4.4.11.2.1.2.1 mkarr 345 | Related Records: 231734 346 | Code Reviewer: Eric Ludlam 347 | Allow for html anchors when matching for debugger output. 348 | Indent line beginning with end according to beginning of block, 349 | not according to the indentation of the previous line. 350 | Respond to "matlab:" anchors (evaluate an M expression). 351 | Accepted job 12245 in Akernel 352 | 353 | Revision 1.4.4.11.2.1.2.1 2005/05/02 23:35:19 mkarr 354 | Related Records: 231734 355 | Code Reviewer: Eric Ludlam 356 | 357 | Allow for html anchors when matching for debugger output. 358 | Indent line beginning with end according to beginning of block, 359 | not according to the indentation of the previous line. 360 | Respond to "matlab:" anchors (evaluate an M expression). 361 | 362 | Revision 1.4.4.11.2.1 2005/01/23 18:39:17 batserve 363 | 2005/01/21 1.4.2.12.2.1 eludlam 364 | Related Records: 250151 365 | Code Reviewer: paulk 366 | Fix mlint dependency problem. 367 | Fix XEmacs compatibility problem. 368 | Add (behind option) experimental shell completion system. 369 | Add (behind comment) hideshow support. 370 | Accepted job 13342 in Ami 371 | 372 | Revision 1.4.2.12.2.1 2005/01/21 13:25:11 eludlam 373 | Related Records: 250151 374 | Code Reviewer: paulk 375 | Fix mlint dependency problem. 376 | Fix XEmacs compatibility problem. 377 | Add (behind option) experimental shell completion system. 378 | Add (behind comment) hideshow support. 379 | 380 | Revision 1.4.2.12 2004/06/16 03:10:04 batserve 381 | 2004/06/10 1.4.2.11.2.1 mkarr 382 | Related Records: 168455 383 | Code Reviewer: Ty Lightner, Eric Ludlam 384 | Changes to support nested functions. 385 | Accepted job 12607 in Amisc 386 | 387 | Revision 1.4.2.11.2.1 2004/06/10 13:47:15 mkarr 388 | Related Records: 168455 389 | Code Reviewer: Ty Lightner, Eric Ludlam 390 | 391 | Changes to support nested functions. 392 | 393 | Revision 1.4.2.11 2004/05/13 02:52:11 batserve 394 | 2004/03/11 1.4.6.12 eludlam 395 | Saved after merging with Amisc (1.4.2.9) 396 | 2004/03/19 1.4.6.13 eludlam 397 | Related Records: 210470 398 | Code Reviewer: Various 399 | Fix header comments. 400 | Fix XEmacs compatibility itimer start. 401 | Fix XEmacs overlay compatibility macros. 402 | Add if(false) next to if(0) special code. 403 | Add support for %{ %} block comments. 404 | Fix problem with Emacs Link when not in use, and add new config item. 405 | Add optional feature for automatically adding a semicolon when needed. 406 | Add variable for lines that don't need semicolons. 407 | Fix menu item for mlint to not require it. 408 | Add -nodesktop to the command line switches. 409 | Fix debugger overlay arrow. 410 | Add `matlab-shell-run-region-or-line' command. 411 | 2004/03/19 1.4.6.14 eludlam 412 | Saved after merging with Amisc (1.4.2.10) 413 | Accepted job 12462 in Amisc 414 | 415 | Revision 1.4.6.14 2004/03/19 21:02:02 eludlam 416 | Saved after merging with Amisc (1.4.2.10) 417 | 418 | Revision 1.4.6.13 2004/03/19 20:59:56 eludlam 419 | Related Records: 210470 420 | Code Reviewer: Various 421 | Fix header comments. 422 | Fix XEmacs compatibility itimer start. 423 | Fix XEmacs overlay compatibility macros. 424 | Add if(false) next to if(0) special code. 425 | Add support for %{ %} block comments. 426 | Fix problem with Emacs Link when not in use, and add new config item. 427 | Add optional feature for automatically adding a semicolon when needed. 428 | Add variable for lines that don't need semicolons. 429 | Fix menu item for mlint to not require it. 430 | Add -nodesktop to the command line switches. 431 | Fix debugger overlay arrow. 432 | Add `matlab-shell-run-region-or-line' command. 433 | 434 | Revision 1.4.6.12 2004/03/11 13:42:54 eludlam 435 | Saved after merging with Amisc (1.4.2.9) 436 | 437 | Revision 1.4.6.11 2004/03/10 18:40:26 eludlam 438 | Related Records: 208705 439 | Code Reviewer: ciolfi 440 | Version number change to 2.3.2 441 | Fix comment for installatin. 442 | Fix matlab-end-of-command (patch from user.) 443 | Add mlint enable/disable to matlab menu. 444 | 445 | Revision 1.4.6.10 2003/07/15 16:49:31 eludlam 446 | Version number change. 447 | Added continue to keyword list. 448 | Added use contributed matlab-generate-latex command. 449 | Revision 1.4.2.9 2004/01/30 22:44:48 batserve 450 | 2004/01/28 1.4.4.9 batserve 451 | 2004/01/23 1.4.8.1 batserve 452 | 2004/01/13 1.4.2.8.2.1 mkarr 453 | Code Reviewer: elijah 454 | merged in changes 455 | 2004/01/20 1.4.2.8.2.2 mkarr 456 | Code Reviewer: Eric Ludlam 457 | Make filter buffer-local. 458 | Put in html "rendering" and other changes for 459 | new handling of source locations. 460 | 2004/01/22 1.4.2.8.2.3 mkarr 461 | Code Reviewer: Eric Ludlam 462 | Adapt to column positions in matlab-url. 463 | Accepted job 7543 in Akernel 464 | Accepted job 13127 in A 465 | Accepted job 11551 in Amisc 466 | Revision 1.4.2.10 2004/03/18 21:17:17 batserve 467 | 2004/03/14 1.4.4.10 batserve 468 | 2004/03/10 1.4.4.9.2.1 padman 469 | Saved after merging with 1.4.6.11 (dev_eludlam) 470 | Accepted job 14370 in A 471 | Accepted job 11967a in Amisc 472 | 473 | Revision 1.4.4.10 2004/03/14 15:30:34 batserve 474 | 2004/03/10 1.4.4.9.2.1 padman 475 | Saved after merging with 1.4.6.11 (dev_eludlam) 476 | Accepted job 14370 in A 477 | 478 | Revision 1.4.4.9.2.1 2004/03/10 20:30:27 padman 479 | Saved after merging with 1.4.6.11 (dev_eludlam) 480 | 481 | Revision 1.4.4.9 2004/01/28 23:06:13 batserve 482 | 2004/01/23 1.4.8.1 batserve 483 | 2004/01/13 1.4.2.8.2.1 mkarr 484 | Code Reviewer: elijah 485 | merged in changes 486 | 2004/01/20 1.4.2.8.2.2 mkarr 487 | Code Reviewer: Eric Ludlam 488 | Make filter buffer-local. 489 | Put in html "rendering" and other changes for 490 | new handling of source locations. 491 | 2004/01/22 1.4.2.8.2.3 mkarr 492 | Code Reviewer: Eric Ludlam 493 | Adapt to column positions in matlab-url. 494 | Accepted job 7543 in Akernel 495 | Accepted job 13127 in A 496 | 497 | Revision 1.4.8.1 2004/01/23 20:35:05 batserve 498 | 2004/01/13 1.4.2.8.2.1 mkarr 499 | Code Reviewer: elijah 500 | merged in changes 501 | 2004/01/20 1.4.2.8.2.2 mkarr 502 | Code Reviewer: Eric Ludlam 503 | Make filter buffer-local. 504 | Put in html "rendering" and other changes for 505 | new handling of source locations. 506 | 2004/01/22 1.4.2.8.2.3 mkarr 507 | Code Reviewer: Eric Ludlam 508 | Adapt to column positions in matlab-url. 509 | Accepted job 7543 in Akernel 510 | 511 | Revision 1.4.2.8.2.3 2004/01/22 16:42:39 mkarr 512 | Code Reviewer: Eric Ludlam 513 | Adapt to column positions in matlab-url. 514 | 515 | Revision 1.4.2.8.2.2 2004/01/20 22:31:16 mkarr 516 | Code Reviewer: Eric Ludlam 517 | Make filter buffer-local. 518 | Put in html "rendering" and other changes for 519 | new handling of source locations. 520 | 521 | Revision 1.4.4.8 2003/05/08 19:45:08 batserve 522 | 2003/04/29 1.4.2.8 batserve 523 | 2003/04/28 1.4.6.9 eludlam 524 | Doc comment update (New file exchange link, matlab shell switches) 525 | Font lock of pragmas 526 | Whitespace mode support. 527 | Accepted job 7691 in Amisc 528 | Accepted job 6970 in A 529 | 530 | Revision 1.4.2.8 2003/04/29 22:45:52 batserve 531 | 2003/04/28 1.4.6.9 eludlam 532 | Doc comment update (New file exchange link, matlab shell switches) 533 | Font lock of pragmas 534 | Whitespace mode support. 535 | Accepted job 7691 in Amisc 536 | 537 | Revision 1.4.6.11 2004/03/10 18:40:26 eludlam 538 | Related Records: 208705 539 | Code Reviewer: ciolfi 540 | Version number change to 2.3.2 541 | Fix comment for installatin. 542 | Fix matlab-end-of-command (patch from user.) 543 | Add mlint enable/disable to matlab menu. 544 | 545 | Revision 1.4.6.10 2003/07/15 16:49:31 eludlam 546 | Version number change. 547 | Added continue to keyword list. 548 | Added use contributed matlab-generate-latex command. 549 | 550 | Revision 1.4.6.9 2003/04/28 13:38:38 eludlam 551 | Doc comment update (New file exchange link, matlab shell switches) 552 | Font lock of pragmas 553 | Whitespace mode support. 554 | 555 | Revision 1.4.6.8 2003/02/19 19:52:11 eludlam 556 | Exclude block verify from save hooks. 557 | Fixed if statement regexp for unreachable code. 558 | Add persistent as a keyword. 559 | 560 | Revision 1.4.6.7 2003/01/06 16:04:51 eludlam 561 | Fill paragraph: Fix to handle comment at end of buffer. 562 | matlab-shell: Fix where kill-local-variables is called. 563 | 564 | Revision 1.4.6.6 2002/10/23 14:56:42 eludlam 565 | Code Reviewer: eludlam 566 | User patch for finding the symbol at point. 567 | 568 | Revision 1.4.6.5 2002/10/03 18:55:27 eludlam 569 | Fix XEmacs itimer issue with block highlighting. 570 | Yoni Wexler contributed patch for indented tic/toc. 571 | Block highlighting tic/toc. 572 | font lock for tic toc. 573 | 574 | Revision 1.4.6.4 2002/09/27 13:31:22 eludlam 575 | Release Version 2.3. 576 | Removed LCD archive entry. 577 | 578 | Revision 1.4.6.3 2002/09/12 13:01:36 eludlam 579 | Added support for matlab-shell reading matlab's history. 580 | Patch originally posted to cssm. 581 | 582 | Revision 1.4.6.2 2002/08/08 18:23:24 eludlam 583 | User patch converts `matlab-shell-command-switches' to a list. 584 | 585 | Revision 1.4.6.1 2002/06/11 18:59:17 eludlam 586 | Fix block highlight matching for timer buffer switch case. 587 | 588 | Revision 1.4 2002/05/08 03:29:39 batserve 589 | Correct docstring to say that future versions of MATLAB may 590 | not require ellipses. 591 | Related Records: 131353 592 | Code Reviewer: eludlam 593 | 594 | Revision 1.4 2002/05/07 20:39:36 paulk 595 | Correct docstring to say that future versions of MATLAB may 596 | not require ellipses. 597 | Related Records: 131353 598 | Code Reviewer: eludlam 599 | 600 | Revision 1.3 2002/05/07 16:44:18 paulk 601 | - Support implied continuation (off by default) 602 | - Add a key binding for find-file-on-path to matlab-shell-mode 603 | - fix banner 604 | - Fix save-and-go to work in unsaved new buffers 605 | Related Records: 131353 606 | Code Reviewer: eludlam 607 | 608 | Revision 1.2 2002/03/20 18:35:20 paulk 609 | Add a patch to matlab-mode from Eric Ludlam to support student edition. 610 | Related Records: 124543 611 | Code Reviewer: eludlam 612 | 613 | Revision 1.1 2002/02/06 20:43:50 paulk 614 | Initial revision 615 | 616 | Revision 1.3 2001/09/07 16:44:38 paulk 617 | Changed "Mathworks" to "MathWorks" and "Matlab" to "MATLAB"? 618 | Related Records: 107855 619 | 620 | Revision 1.2 2001/09/06 16:41:39 paulk 621 | save-and-go and run-region now invoke their eei 622 | equivalents when eei is active. 623 | Related Records: 99176 624 | Code Reviewer: eludlam 625 | 626 | Revision 1.1 2001/08/31 20:45:51 paulk 627 | Initial revision 628 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation: 2 | 3 | ** DEPENDANCIES 4 | 5 | This matlab-emacs build system now requires the CEDET suite. 6 | If you are using Emacs version 23.2 or later, you should have 7 | everything you need. 8 | 9 | For older versions of Emacs, visit: 10 | 11 | http://cedet.sf.net 12 | 13 | The build system uses EDE for project management, Makefile creation, 14 | and autoload generation. 15 | 16 | ** BUILD 17 | 18 | To build: 19 | 20 | make 21 | 22 | To build using an alternate version of CEDET: 23 | 24 | make CEDET_PATH=~/my/cedet/lisp/ 25 | 26 | It is possible to use matlab.el, and associated programs without this 27 | extra package. To do so, install and compile only those lisp files 28 | you need. 29 | 30 | ** FULL INSTALL 31 | 32 | To install all the Emacs tools for MATLAB, add this to your .emacs file: 33 | 34 | (add-to-list 'load-path "~/path/to/matlab_el") 35 | (require 'matlab-load) 36 | 37 | ** matlab.el: 38 | 39 | If you want to only use matlab.el for editing your code, and do not 40 | want to try the other tools, you can do that also, though the install 41 | code you need is more complex: 42 | 43 | 44 | Put the this file as "matlab.el" somewhere on your load path, then 45 | add this to your .emacs or site-init.el file: 46 | 47 | (autoload 'matlab-mode "matlab" "Enter MATLAB mode." t) 48 | (setq auto-mode-alist (cons '("\\.m\\'" . matlab-mode) auto-mode-alist)) 49 | (autoload 'matlab-shell "matlab" "Interactive MATLAB mode." t) 50 | 51 | ** CUSTOMIZATION: 52 | 53 | User Level customizations (You need not use them all): 54 | (setq matlab-indent-function-body t) ; if you want function bodies indented 55 | (setq matlab-verify-on-save-flag nil) ; turn off auto-verify on save 56 | (defun my-matlab-mode-hook () 57 | (setq fill-column 76)) ; where auto-fill should wrap 58 | (add-hook 'matlab-mode-hook 'my-matlab-mode-hook) 59 | (defun my-matlab-shell-mode-hook () 60 | '()) 61 | (add-hook 'matlab-shell-mode-hook 'my-matlab-shell-mode-hook) 62 | 63 | Please read the mode help for matlab-mode for additional 64 | configuration options. 65 | 66 | Syntax highlighting: 67 | To get font-lock try adding this for older emacsen: 68 | (font-lock-mode 1) 69 | Or for newer versions of Emacs: 70 | (global-font-lock-mode t) 71 | To get hilit19 support try adding: 72 | (matlab-mode-hilit) 73 | 74 | This package requires easymenu, tempo, and derived. 75 | This package will optionally use custom, shell, and gud. 76 | This package supports language specific extensions in imenu, func-menu, 77 | speedbar, font-lock, and hilit19. 78 | 79 | ** tlc.el 80 | 81 | To use this mode without using the full install, put the this file 82 | into your load path, and add the following to your .emacs file: 83 | 84 | (require 'tlc) 85 | or 86 | (autoload 'tlc-mode "tlc" "tlc Editing Mode" t) 87 | (add-to-list 'auto-mode-alist '("\\.tlc$" . tlc-mode)) 88 | (setq tlc-indent-function t) 89 | 90 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Automatically Generated Makefile by EDE. 2 | # For use with: make 3 | # Relative File Name: Makefile 4 | # 5 | # DO NOT MODIFY THIS FILE OR YOUR CHANGES MAY BE LOST. 6 | # EDE is the Emacs Development Environment. 7 | # http://cedet.sourceforge.net/ede.shtml 8 | # 9 | 10 | top="$(CURDIR)"/ 11 | ede_FILES=Project.ede Makefile 12 | 13 | CEDET_PATH:=~/cedet/trunk/lisp 14 | 15 | EMACS=emacs 16 | EMACSFLAGS=-batch --no-site-file --eval '(setq debug-on-error t)' 17 | LOADPATH= ./ $(CEDET_PATH)/cedet/ 18 | require=$(foreach r,$(1),(require (quote $(r)))) 19 | LOADDEFS=matlab-load.el 20 | LOADDIRS=. 21 | misc_MISC=ChangeLog ChangeLog.old1 ChangeLog.old2 INSTALL README dl_emacs_support.m 22 | lisp_LISP=matlab.el mlint.el tlc.el matlab-publish.el linemark.el 23 | cedet_LISP=semantic-matlab.el semanticdb-matlab.el srecode-matlab.el cedet-matlab.el company-matlab-shell.el company-matlab.el 24 | VERSION=3.3.2 25 | DISTDIR=$(top)matlab-emacs-$(VERSION) 26 | 27 | 28 | 29 | all: autoloads misc lisp cedet toolbox Templates 30 | 31 | .PHONY: clean-autoloads 32 | clean-autoloads: 33 | rm -f $(LOADDEFS) 34 | 35 | .PHONY: autoloads 36 | autoloads: 37 | $(EMACS) $(EMACSFLAGS) $(AUTOGENFLAGS) $(addprefix -L ,$(LOADPATH)) --eval '(progn $(call require, $(PRELOADS)) (setq generated-autoload-file "$(abspath $(LOADDEFS))"))' -f batch-update-autoloads $(abspath $(LOADDIRS)) 38 | 39 | 40 | misc: 41 | @ 42 | 43 | %.elc: %.el 44 | $(EMACS) $(EMACSFLAGS) $(addprefix -L ,$(LOADPATH)) --eval '(progn $(call require, $(PRELOADS)))' -f batch-byte-compile $^ 45 | 46 | .PHONY: lisp 47 | lisp: $(addsuffix c, $(lisp_LISP)) 48 | 49 | .PHONY: cedet 50 | cedet: $(addsuffix c, $(cedet_LISP)) 51 | 52 | .PHONY:toolbox 53 | toolbox: 54 | $(MAKE) -C toolbox 55 | 56 | .PHONY:Templates 57 | Templates: 58 | $(MAKE) -C templates 59 | 60 | tags: 61 | $(MAKE) -C toolbox/ $(MFLAGS) $@ 62 | $(MAKE) -C templates/ $(MFLAGS) $@ 63 | 64 | 65 | clean: 66 | rm -f *.elc 67 | 68 | .PHONY: dist 69 | 70 | dist: autoloads 71 | rm -rf $(DISTDIR) 72 | mkdir $(DISTDIR) 73 | cp matlab-load.el $(misc_MISC) $(lisp_LISP) $(cedet_LISP) $(ede_FILES) $(DISTDIR) 74 | $(MAKE) -C toolbox $(MFLAGS) DISTDIR=$(DISTDIR)/toolbox dist 75 | $(MAKE) -C templates $(MFLAGS) DISTDIR=$(DISTDIR)/templates dist 76 | tar -cvzf $(DISTDIR).tar.gz $(DISTDIR) 77 | rm -rf $(DISTDIR) 78 | 79 | Makefile: Project.ede 80 | @echo Makefile is out of date! It needs to be regenerated by EDE. 81 | @echo If you have not modified Project.ede, you can use 'touch' to update the Makefile time stamp. 82 | @false 83 | 84 | 85 | 86 | # End of Makefile 87 | -------------------------------------------------------------------------------- /Project.ede: -------------------------------------------------------------------------------- 1 | ;; Object ede-proj-project 2 | ;; EDE Project Files are auto generated: Do Not Edit 3 | (ede-proj-project "ede-proj-project" 4 | :file "Project.ede" 5 | :name "matlab-emacs" 6 | :version "3.3.2" 7 | :targets 8 | (list 9 | (ede-proj-target-elisp-autoloads "autoloads" 10 | :name "autoloads" 11 | :path "" 12 | :autoload-file "matlab-load.el") 13 | (ede-proj-target-makefile-miscelaneous "misc" 14 | :name "misc" 15 | :path "" 16 | :source '("ChangeLog" "ChangeLog.old1" "ChangeLog.old2" "INSTALL" "README" "dl_emacs_support.m")) 17 | (ede-proj-target-elisp "lisp" 18 | :name "lisp" 19 | :path "" 20 | :source '("matlab.el" "mlint.el" "tlc.el" "matlab-publish.el" "linemark.el") 21 | :versionsource '("matlab.el") 22 | :aux-packages '("matlab")) 23 | (ede-proj-target-elisp "cedet" 24 | :name "cedet" 25 | :path "" 26 | :source '("semantic-matlab.el" "semanticdb-matlab.el" "srecode-matlab.el" "cedet-matlab.el" "company-matlab-shell.el" "company-matlab.el") 27 | :aux-packages '("semantic")))) 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is an unofficial port of the MATLAB and Emacs integration mode from the project CVS repo (http://sourceforge.net/projects/matlab-emacs/) to GitHub (as of March 2015). The following changes were added on top of the original project: 2 | 3 | 1. New company-matlab.el backend that works both inside the Matlab shell and in Matlab files 4 | 2. New flycheck-mlint back-end for flycheck which uses mlint to highlight warnings in Matlab files. 5 | 3. Fixed additional newlines and incorrect formatting of prompt after completion 6 | 4. Fixed version parsing for new Matlab versions 7 | 5. Re-enabled HTML parsing 8 | 9 | # Installation 10 | 11 | Add the following to your .emacs file: 12 | 13 | ``` 14 | ;; Replace path below to be where your matlab.el file is. 15 | (add-to-list 'load-path "~/path/to/matlab-emacs") 16 | (load-library "matlab-load") 17 | 18 | ;; Enable CEDET feature support for MATLAB code. (Optional) 19 | ;; (matlab-cedet-setup) 20 | ``` 21 | 22 | To use the company completion engine, add company-matlab to company-mode backends list: 23 | 24 | ``` 25 | (add-to-list 'company-backends 'company-anaconda) 26 | ``` 27 | 28 | **NOTE!** In order for the completions to work Matlab shell must be started! 29 | 30 | To use the flycheck mlint backedn, add the following to your init file: 31 | 32 | ``` 33 | (eval-after-load 'flycheck 34 | '(require 'flycheck-matlab-mlint)) 35 | ``` 36 | 37 | **NOTE!** Matlab binary folder, e.g. `/opt/MATLAB/R2013a/bin` must be in your path for this to work. 38 | 39 | 40 | # Original Project Documentation 41 | 42 | ## Finding Updates 43 | 44 | ### Releases 45 | 46 | The most recent version of matlab.el is always in CVS. 47 | 48 | You can get an old downloader for matlab-emacs from MATLAB File Exchange. 49 | 50 | Category: 51 | http://www.mathworks.com/matlabcentral/fileexchange/loadCategory.do?objectId=19&objectType=Category 52 | This File 53 | http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=104&objectType=file 54 | 55 | Older versions of matlab.el can be found as matlab.el.1.10.1 56 | for emacsen that do not have the latest additional utilities such 57 | as tempo and derived. 58 | 59 | matlab.el and mlint.el has shipped on MATLAB CDs starting with 6.5 60 | (R13). Updates after a release of MATLAB will be made to MATLAB 61 | Central and announced on the mailing list. 62 | 63 | matlab.el and mlint.el will no longer ship on MATLAB CDs starting 64 | with MATLAB release R2008b. If you are using a version of MATLAB 65 | from before R2008a, you will want to use the version of mlint from 66 | that CD. 67 | 68 | ### CVS 69 | 70 | matlab-emacs is available via CVS from SourceForge. 71 | 72 | Homepage: 73 | http://matlab-emacs.sf.net 74 | 75 | Project Page: 76 | http://sourceforge.net/projects/matlab-emacs 77 | 78 | CVS Repository: 79 | http://matlab-emacs.cvs.sourceforge.net/matlab-emacs 80 | 81 | If you do not have a CVS client on your machine, you can use the 82 | MATLAB script dl_emacs_support.m to download a fresh copy of the 83 | matlab.el sources. 84 | 85 | http://matlab-emacs.cvs.sourceforge.net/viewvc/matlab-emacs/matlab-emacs/dl_emacs_support.m 86 | 87 | ### Dependancies 88 | 89 | MATLAB-Emacs can use the CEDET suite for the following items: 90 | - Modifying the build system (Makefiles, etc) 91 | - mlint (uses EIEIO object system) 92 | - parsing/completion (uses semantic parsing system) 93 | - some template insertion features 94 | 95 | As of Emacs 23.2, CEDET is included in Emacs, and nothing extra 96 | is needed to satisfy that dependency. 97 | 98 | For older versions of Emacs: 99 | 100 | See http://cedet.sf.net for downloading CEDET. 101 | 102 | If you only want to use matlab.el for editing code or running the 103 | MATLAB shell, you DO NOT need to install CEDET. 104 | 105 | If you do want to use CEDET, add the following to your .emacs file: 106 | 107 | (matlab-cedet-setup) 108 | 109 | ## Mailing List: 110 | 111 | ### New Mailing List 112 | 113 | A new matlab-emacs-discuss mailing lisit has been created at 114 | SourceForge. Use this list to get updates on new releases and 115 | discuss topics relivant to the matlab-emacs project. 116 | 117 | http://lists.sourceforge.net/mailman/listinfo/matlab-emacs-discuss 118 | 119 | ### Old Mailing List 120 | 121 | The original mailing list where beta versions of matlab.el were 122 | posted, and where comments, questions, bug reports, and answers to 123 | questions could be sent. If you were subscribed to this list, 124 | please unsubscribe, and subscribe to the new list above. 125 | 126 | to unsubscribe, send email with the body of: "unsubscribe matlab-emacs" 127 | -------------------------------------------------------------------------------- /cedet-matlab.el: -------------------------------------------------------------------------------- 1 | ;;; cedet-matlab.el --- CEDET Setup support 2 | ;; 3 | ;; Copyright (C) 2009, 2012 Eric Ludlam 4 | ;; 5 | ;; Author: Eric Ludlam 6 | ;; X-RCS: $Id$ 7 | ;; 8 | ;; This program is free software; you can redistribute it and/or 9 | ;; modify it under the terms of the GNU General Public License as 10 | ;; published by the Free Software Foundation; either version 2, or (at 11 | ;; your option) any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, but 14 | ;; WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | ;; General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with this program; see the file COPYING. If not, write to 20 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 | ;; Boston, MA 02110-1301, USA. 22 | 23 | ;;; Commentary: 24 | ;; 25 | ;; Setup miscelaneous CEDET tools to work with MATLAB. 26 | 27 | ;;; Code: 28 | ;;;###autoload 29 | (defun matlab-cedet-setup () 30 | "Update various paths to get SRecode to identify our macros." 31 | (interactive) 32 | 33 | ;; Setup Semantic parser: 34 | (add-hook 'matlab-mode-hook 'semantic-default-matlab-setup) 35 | 36 | ;; Setup semanticdb for MATLAB support: 37 | (require 'semanticdb-matlab) 38 | 39 | ;; Setup Semantic Recoder (Template support for MATLAB and TLC.): 40 | (let* ((lib (locate-library "matlab.el" t)) 41 | (ededir (file-name-directory lib)) 42 | (tmpdir (file-name-as-directory 43 | (expand-file-name "templates" ededir)))) 44 | (when (not tmpdir) 45 | (error "Unable to locate MATLAB Templates directory")) 46 | 47 | ;; Rig up the map. 48 | (condition-case nil 49 | (require 'srecode-map) 50 | (error (require 'srecode/map))) 51 | 52 | (add-to-list 'srecode-map-load-path tmpdir) 53 | (srecode-map-update-map t) 54 | ) 55 | 56 | 57 | ) 58 | 59 | 60 | (provide 'cedet-matlab) 61 | ;;; cedet-matlab.el ends here 62 | -------------------------------------------------------------------------------- /company-matlab-shell.el: -------------------------------------------------------------------------------- 1 | ;;; company-matlab-shell.el --- a matlab-shell-mode completion back-end for AUCTeX 2 | ;; 3 | ;; Copyright (C) 2009 David Engster 4 | ;; 5 | ;; This program is free software; you can redistribute it and/or 6 | ;; modify it under the terms of the GNU General Public License 7 | ;; as published by the Free Software Foundation; either version 2 8 | ;; of the License, or (at your option) any later version. 9 | ;; 10 | ;; This program is distributed in the hope that it will be useful, 11 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ;; GNU General Public License for more details. 14 | ;; 15 | ;; You should have received a copy of the GNU General Public License 16 | ;; along with this program. If not, see . 17 | 18 | (condition-case nil 19 | (require 'company) 20 | (error nil)) 21 | (eval-when-compile (require 'cl)) 22 | (require 'matlab) 23 | 24 | ;; the following code is mostly taken from matlab.el, (C) Eric M. Ludlam 25 | (defun company-matlab-shell-tab () 26 | "Send [TAB] to the currently running matlab process and retrieve completion." 27 | (goto-char (point-max)) 28 | (let ((inhibit-field-text-motion t)) 29 | (beginning-of-line)) 30 | (re-search-forward comint-prompt-regexp) 31 | (let* ((lastcmd (buffer-substring (point) (matlab-point-at-eol))) 32 | (tempcmd lastcmd) 33 | (completions nil) 34 | (limitpos nil)) 35 | ;; search for character which limits completion, and limit command to it 36 | (setq limitpos 37 | (if (string-match ".*\\([( /[,;=']\\)" lastcmd) 38 | (1+ (match-beginning 1)) 39 | 0)) 40 | (setq lastcmd (substring lastcmd limitpos)) 41 | ;; Whack the old command so we can insert it back later. 42 | (delete-region (+ (point) limitpos) (matlab-point-at-eol)) 43 | ;; double every single quote 44 | (while (string-match "[^']\\('\\)\\($\\|[^']\\)" tempcmd) 45 | (setq tempcmd (replace-match "''" t t tempcmd 1))) 46 | ;; collect the list 47 | (setq completions (matlab-shell-completion-list tempcmd)) 48 | (goto-char (point-max)) 49 | (insert lastcmd) 50 | completions)) 51 | 52 | (defun company-matlab-shell-grab-symbol () 53 | (when (string= (buffer-name (current-buffer)) (concat "*" matlab-shell-buffer-name "*")) 54 | (save-excursion 55 | (goto-char (point-max)) 56 | (let ((inhibit-field-text-motion t)) 57 | (beginning-of-line)) 58 | (re-search-forward comint-prompt-regexp) 59 | (let* ((lastcmd (buffer-substring (point) (matlab-point-at-eol))) 60 | limitpos) 61 | (setq limitpos 62 | (if (string-match ".*\\([( /[,;=']\\)" lastcmd) 63 | (1+ (match-beginning 1)) 64 | 0)) 65 | (substring-no-properties lastcmd limitpos))))) 66 | 67 | 68 | (defun company-matlab-shell-get-completions () 69 | (when (string= (buffer-name (current-buffer)) (concat "*" matlab-shell-buffer-name "*")) 70 | (mapcar 'car (company-matlab-shell-tab)))) 71 | 72 | ;;;###autoload 73 | (defun company-matlab-shell (command &optional arg &rest ignored) 74 | "A `company-mode' completion back-end for Matlab-Shell." 75 | (interactive (list 'interactive)) 76 | (case command 77 | ('interactive (company-begin-backend 'company-matlab-shell)) 78 | ('prefix (company-matlab-shell-grab-symbol)) 79 | ('candidates (company-matlab-shell-get-completions)) 80 | ('sorted t))) 81 | 82 | (provide 'company-matlab-shell) 83 | ;;; company-matlab-shell.el ends here 84 | -------------------------------------------------------------------------------- /company-matlab.el: -------------------------------------------------------------------------------- 1 | ;;; company-matlab.el --- A matlab-mode and matlab-shell mode completion back-end 2 | 3 | ;;; Commentary: 4 | ;; Copyright (C) 2009 David Engster 5 | ;; Copyright (C) 2015 Andrzej Pronobis 6 | ;; 7 | ;; This program is free software; you can redistribute it and/or 8 | ;; modify it under the terms of the GNU General Public License 9 | ;; as published by the Free Software Foundation; either version 2 10 | ;; of the License, or (at your option) any later version. 11 | ;; 12 | ;; This program is distributed in the hope that it will be useful, 13 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | ;; GNU General Public License for more details. 16 | ;; 17 | ;; You should have received a copy of the GNU General Public License 18 | ;; along with this program. If not, see . 19 | 20 | ;;; Code: 21 | ;; The following code is largely based on the company-matlab-shell.el mode. 22 | 23 | (require 'cl-lib) 24 | (condition-case nil 25 | (require 'company) 26 | (error nil)) 27 | (require 'matlab) 28 | 29 | 30 | (defun company-matlab-get-completions (cmd) 31 | "Retrieve completions for the given command CMD." 32 | (let* ((pt-start (save-excursion (matlab-beginning-of-command) (point))) 33 | (pt-shell nil) 34 | (cmd (buffer-substring-no-properties pt-start (point))) 35 | (completions nil) 36 | (pre-shell-line nil) 37 | (post-shell-line nil) 38 | (shell-buf (get-buffer (concat "*" matlab-shell-buffer-name "*"))) 39 | (inhibit-quit nil)) ; For some reason this is set and produces error 40 | ;; Remove everything before ; 41 | (setq cmd (replace-regexp-in-string ".*;" "" cmd)) 42 | ;; Replace every ' with '''' 43 | (setq cmd (replace-regexp-in-string "'" "''''" cmd)) 44 | (with-current-buffer shell-buf 45 | ;; Remember shell cursor position 46 | (setq pt-shell (point)) 47 | (setq pre-shell-line (save-excursion 48 | (let ((inhibit-field-text-motion t)) 49 | (beginning-of-line)) 50 | (point))) 51 | ;; Get completions 52 | (setq completions (let ((comint-inhibit-carriage-motion t)) 53 | (matlab-shell-completion-list cmd)))) 54 | ;; Restore point if it was misplaced in console 55 | (dolist (win (get-buffer-window-list shell-buf nil t)) 56 | (with-selected-window win 57 | (setq post-shell-line (save-excursion 58 | (let ((inhibit-field-text-motion t)) 59 | (beginning-of-line)) 60 | (point))) 61 | (goto-char (+ post-shell-line (- pt-shell pre-shell-line))))) 62 | (mapcar 'car completions))) 63 | 64 | (defun company-matlab-grab-command () 65 | "Return the symbol to complete together with length of all relevant context." 66 | (let* ((symbol (company-grab-symbol)) 67 | (pt-beg (save-excursion (matlab-beginning-of-command) (point))) 68 | (pt-end (point)) 69 | (len (- pt-end pt-beg))) 70 | (when (and (> len 0) 71 | (not (eq (preceding-char) ?\s))) ; Do not complete just after space 72 | (cons symbol len)))) 73 | 74 | (defun company-matlab-prefix () 75 | "Check if all conditions are met and provide prefix." 76 | (and (derived-mode-p 'matlab-mode 'matlab-shell-mode) 77 | (not (matlab-cursor-in-string t)) 78 | (not (matlab-cursor-in-comment)) 79 | (matlab-shell-active-p) 80 | (or (company-matlab-grab-command) 'stop))) 81 | 82 | ;;;###autoload 83 | (defun company-matlab (command &optional arg &rest ignored) 84 | "A `company-mode' completion back-end for matlab-mode and matlab-shell-mode." 85 | (interactive (list 'interactive)) 86 | (cl-case command 87 | ('interactive (company-begin-backend 'company-matlab)) 88 | ('prefix (company-matlab-prefix)) 89 | ('candidates (company-matlab-get-completions arg)) 90 | ('sorted t))) 91 | 92 | (provide 'company-matlab) 93 | ;;; company-matlab.el ends here 94 | -------------------------------------------------------------------------------- /dl_emacs_support.m: -------------------------------------------------------------------------------- 1 | function dl_emacs_support(varargin) 2 | % Download MATLAB support files for Emacs 3 | % 4 | % DL_EMACS_SUPPRT - download all Emacs support files into the 5 | % current directory. 6 | % 7 | % DL_EMACS_SUPPORT(FILESET) - download a FILESET of Emacs support. 8 | % Sets are: 9 | % dl - Download a new version of this download script. 10 | % core - Just the core MATLAB support files. 11 | % tlc - Just the core MATLAB/TLC support files. 12 | % cedet - Core, plus additional support for MATLAB using CEDET support. 13 | % Learn more about CEDET at: http://cedet.sf.net 14 | % support - Just the build files and READMEs for compiling. 15 | % all - All files 16 | % 17 | % DL_EMACS_SUPPORT(FILESET,DEST) - download FILESET and save in 18 | % destination directory DEST 19 | % 20 | % For the most reliable refresh of the repository, run these two 21 | % commands, the frist will make sure the downloader is current. 22 | % 23 | % dl_emacs_support dl 24 | % dl_emacs_support 25 | % 26 | % On unix, you can then execute: 27 | % 28 | % !make 29 | % 30 | % to compile. 31 | 32 | po = inputParser; 33 | 34 | addOptional(po, 'fileset', 'all', @ischar) 35 | addOptional(po, 'destination', pwd, @ischar) 36 | 37 | po.parse(varargin{:}); 38 | 39 | stuff = po.Results; 40 | 41 | if exist(stuff.destination,'dir') ~= 7 42 | error(['The folder: ''',stuff.destination, ''', does not exist.']); 43 | end 44 | 45 | downloader = { 'dl_emacs_support.m' }; 46 | 47 | coreFiles = { 'matlab-load.el' 'matlab.el' 'mlint.el' ... 48 | 'matlab-publish.el' 'company-matlab-shell.el' ... 49 | 'linemark.el' ... 50 | 'toolbox/emacsinit.m' 'toolbox/opentoline.m' 'toolbox/emacsdocomplete.m' }; 51 | tlcFiles = { 'tlc.el' }; 52 | cedetFiles = { 'cedet-matlab.el' 'semantic-matlab.el' ... 53 | 'semanticdb-matlab.el' 'srecode-matlab.el' ... 54 | 'templates/srecode-matlab.srt' }; 55 | supportFiles = { 'README' 'INSTALL' 'ChangeLog' ... 56 | 'Project.ede' 'Makefile' ... 57 | 'toolbox/Project.ede' 'toolbox/Makefile' ... 58 | 'templates/Project.ede' 'templates/Makefile'}; 59 | 60 | switch stuff.fileset 61 | case 'dl' 62 | getfiles(downloader); 63 | case 'core' 64 | mktoolboxdir 65 | getfiles(coreFiles); 66 | case 'tlc' 67 | mktoolboxdir 68 | getfiles(coreFiles); 69 | getfiles(tlcFiles); 70 | case 'cedet' 71 | mktoolboxdir 72 | getfiles(coreFiles); 73 | mktemplatedir; 74 | getfiles(cedetFiles); 75 | case 'support' 76 | mktemplatedir; 77 | getfiles(supportFiles); 78 | case 'all' 79 | mktoolboxdir 80 | getfiles(coreFiles); 81 | getfiles(tlcFiles); 82 | mktemplatedir; 83 | getfiles(cedetFiles); 84 | getfiles(supportFiles); 85 | otherwise 86 | error('Unknown fileset %s.', stuff.fileset); 87 | end 88 | 89 | function mktemplatedir 90 | templateDir = fullfile(stuff.destination,'templates'); 91 | if ~exist(templateDir,'dir') 92 | mkdir(templateDir); 93 | end 94 | end 95 | 96 | function mktoolboxdir 97 | toolboxDir = fullfile(stuff.destination,'toolbox'); 98 | if ~exist(toolboxDir,'dir') 99 | mkdir(toolboxDir); 100 | end 101 | end 102 | 103 | function getfiles(fList) 104 | for i = 1:length(fList) 105 | file = fList{i}; 106 | destFullFile = fullfile(stuff.destination,file); 107 | [ contents status ] = ... 108 | urlread(['http://matlab-emacs.cvs.sourceforge.net/viewvc/*checkout*/matlab-emacs/matlab-emacs/',... 109 | file,'?revision=HEAD']); 110 | if ~status 111 | fprintf('Unable to download %s.\n', file); 112 | else 113 | fid = fopen(destFullFile,'w'); 114 | fwrite(fid,contents); 115 | fclose(fid); 116 | fprintf('Successfully downloaded and created: ''%s''.\n',... 117 | destFullFile); 118 | end 119 | end 120 | end 121 | end 122 | 123 | -------------------------------------------------------------------------------- /flycheck-matlab-mlint.el: -------------------------------------------------------------------------------- 1 | ;;; flycheck-mlint.el --- Flycheck checker using Matlab mlint 2 | 3 | ;; Copyright (C) 2015 Andrzej Pronobis 4 | ;; Author: Andrzej Pronobis 5 | 6 | ;; This file is not part of GNU Emacs. 7 | 8 | ;; This program is free software; you can redistribute it and/or modify 9 | ;; it under the terms of the GNU General Public License as published by 10 | ;; the Free Software Foundation, either version 3 of the License, or 11 | ;; (at your option) any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, 14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | ;; GNU General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with this program. If not, see . 20 | 21 | ;;; Commentary: 22 | 23 | ;; This is extension for Flycheck. 24 | ;; To use, add the following to your init: 25 | ;; (eval-after-load 'flycheck 26 | ;; '(require 'flycheck-matlab-mlint)) 27 | 28 | ;;; Code: 29 | 30 | (require 'flycheck) 31 | 32 | ;; Taken from mlint.el by Eric M. Ludlam 33 | (defvar flycheck-matlab-mlint-platform 34 | (cond ((eq system-type 'darwin) 35 | (if (string-match "i386" system-configuration) 36 | (let ((mt (getenv "MACHTYPE"))) 37 | (if (and (stringp mt) (string= "x86_32" mt)) 38 | ;; This hack is bad since an Emacs started from 39 | ;; the doc doesn't have this variable, thus by defaulting 40 | ;; to checking the 32 bit (not common anymore) version, 41 | ;; we'll get the right answer most of the time. 42 | "maci" "maci64")) 43 | "mac")) 44 | ((eq system-type 'gnu/linux) 45 | (cond ((string-match "64\\|i686" system-configuration) 46 | "glnxa64") 47 | (t "glnx86"))) 48 | ((eq system-type 'solaris) 49 | "sol2") 50 | ((eq system-type 'hpux) 51 | "hpux") 52 | ((eq system-type 'windows-nt) 53 | ;; Thought about checking the env PROCESSOR_ARCHITEW6432, 54 | ;; but this said AMD on my Intel, which seemed suspicious. 55 | (let ((proc (getenv "PROCESSOR_IDENTIFIER"))) 56 | (if (and (stringp proc) (string-match "64" proc)) 57 | "win64" 58 | "win32"))) 59 | (t "unknown")) 60 | "Platform we are running mlint on.") 61 | 62 | (defvar flycheck-matlab-mlint-executable-path 63 | (or (executable-find 64 | (concat 65 | (file-name-as-directory flycheck-matlab-mlint-platform) 66 | "mlint")) 67 | "") 68 | "Default full executable path.") 69 | 70 | (flycheck-def-executable-var matlab-mlint "/mlint") 71 | 72 | (flycheck-define-command-checker 'matlab-mlint 73 | "A Matlab checker based on mlint." 74 | :command `(,flycheck-matlab-mlint-executable-path source) 75 | :error-patterns 76 | '((warning line-start "L " line " (C " (1+ digit) "): " (message) line-end)) 77 | :modes '(matlab-mode)) 78 | 79 | (add-to-list 'flycheck-checkers 'matlab-mlint 'append) 80 | 81 | (provide 'flycheck-matlab-mlint) 82 | ;;; flycheck-matlab-mlint.el ends here 83 | -------------------------------------------------------------------------------- /linemark.el: -------------------------------------------------------------------------------- 1 | ;;; linemark.el --- Manage groups of lines with marks. 2 | ;; 3 | ;; Author: Eric M. Ludlam 4 | ;; Maintainer: Eric M. Ludlam 5 | ;; Created: Dec 1999 6 | ;; Keywords: lisp 7 | ;; 8 | ;; Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Eric M. Ludlam 9 | ;; 10 | ;; This program is free software; you can redistribute it and/or modify 11 | ;; it under the terms of the GNU General Public License as published by 12 | ;; the Free Software Foundation; either version 2, or (at your option) 13 | ;; any later version. 14 | ;; 15 | ;; This program is distributed in the hope that it will be useful, 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | ;; GNU General Public License for more details. 19 | ;; 20 | ;; You should have received a copy of the GNU General Public License 21 | ;; along with GNU Emacs; see the file COPYING. If not, write to the 22 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 23 | ;; Boston, MA 02110-1301, USA. 24 | ;; 25 | ;;; Commentary: 26 | ;; 27 | ;; This is a library of routines which help Lisp programmers manage 28 | ;; groups of marked lines. Common uses for marked lines are debugger 29 | ;; breakpoints and watchpoints, or temporary line highlighting. It 30 | ;; could also be used to select elements from a list. 31 | ;; 32 | ;; The reason this tool is useful is because cross-emacs overlay 33 | ;; management can be a pain, and overlays are certainly needed for use 34 | ;; with font-lock. 35 | 36 | (require 'eieio) 37 | 38 | (eval-when-compile 39 | (require 'cl)) 40 | 41 | ;;; Code: 42 | ;; Compatibility 43 | (eval-and-compile 44 | (if (featurep 'xemacs) 45 | (progn 46 | (defalias 'linemark-overlay-live-p 'extent-live-p) 47 | (defalias 'linemark-make-overlay 'make-extent) 48 | (defalias 'linemark-overlay-put 'set-extent-property) 49 | (defalias 'linemark-overlay-get 'extent-property) 50 | (defalias 'linemark-delete-overlay 'delete-extent) 51 | (defalias 'linemark-overlays-at 52 | (lambda (pos) (extent-list nil pos pos))) 53 | (defalias 'linemark-overlays-in 54 | (lambda (beg end) (extent-list nil beg end))) 55 | (defalias 'linemark-overlay-buffer 'extent-buffer) 56 | (defalias 'linemark-overlay-start 'extent-start-position) 57 | (defalias 'linemark-overlay-end 'extent-end-position) 58 | (defalias 'linemark-next-overlay-change 'next-extent-change) 59 | (defalias 'linemark-previous-overlay-change 'previous-extent-change) 60 | (defalias 'linemark-overlay-lists 61 | (lambda () (list (extent-list)))) 62 | (defalias 'linemark-overlay-p 'extentp) 63 | ) 64 | (defalias 'linemark-overlay-live-p 'overlay-buffer) 65 | (defalias 'linemark-make-overlay 'make-overlay) 66 | (defalias 'linemark-overlay-put 'overlay-put) 67 | (defalias 'linemark-overlay-get 'overlay-get) 68 | (defalias 'linemark-delete-overlay 'delete-overlay) 69 | (defalias 'linemark-overlays-at 'overlays-at) 70 | (defalias 'linemark-overlays-in 'overlays-in) 71 | (defalias 'linemark-overlay-buffer 'overlay-buffer) 72 | (defalias 'linemark-overlay-start 'overlay-start) 73 | (defalias 'linemark-overlay-end 'overlay-end) 74 | (defalias 'linemark-next-overlay-change 'next-overlay-change) 75 | (defalias 'linemark-previous-overlay-change 'previous-overlay-change) 76 | (defalias 'linemark-overlay-lists 'overlay-lists) 77 | (defalias 'linemark-overlay-p 'overlayp) 78 | )) 79 | 80 | (defgroup linemark nil 81 | "Line marking/highlighting." 82 | :group 'tools 83 | ) 84 | 85 | (eval-and-compile 86 | ;; These faces need to exist to show up as valid default 87 | ;; entries in the classes defined below. 88 | 89 | (defface linemark-stop-face '((((class color) (background light)) 90 | (:background "#ff8888")) 91 | (((class color) (background dark)) 92 | (:background "red3"))) 93 | "*Face used to indicate a STOP type line." 94 | :group 'linemark) 95 | 96 | (defface linemark-caution-face '((((class color) (background light)) 97 | (:background "yellow")) 98 | (((class color) (background dark)) 99 | (:background "yellow4"))) 100 | "*Face used to indicate a CAUTION type line." 101 | :group 'linemark) 102 | 103 | (defface linemark-go-face '((((class color) (background light)) 104 | (:background "#88ff88")) 105 | (((class color) (background dark)) 106 | (:background "green4"))) 107 | "*Face used to indicate a GO, or OK type line." 108 | :group 'linemark) 109 | 110 | (defface linemark-funny-face '((((class color) (background light)) 111 | (:background "cyan")) 112 | (((class color) (background dark)) 113 | (:background "blue3"))) 114 | "*Face used for elements with no particular criticality." 115 | :group 'linemark) 116 | 117 | ) 118 | 119 | (defclass linemark-entry () 120 | ((filename :initarg :filename 121 | :type string 122 | :documentation "File name for this mark.") 123 | (line :initarg :line 124 | :type number 125 | :documentation "Line number where the mark is.") 126 | (face :initarg :face 127 | ; Something created w/ defface is not a face in XEmacs. 128 | ; :type face 129 | :initform linemark-caution-face 130 | :documentation "The face to use for display.") 131 | (parent :documentation "The parent `linemark-group' containing this." 132 | :type linemark-group) 133 | (overlay :documentation "Overlay created to show this mark." 134 | :type (or linemark-overlay null) 135 | :initform nil 136 | :protection protected)) 137 | "Track a file/line associations with overlays used for display.") 138 | 139 | (defclass linemark-group () 140 | ((marks :initarg :marks 141 | :type list 142 | :initform nil 143 | :documentation "List of `linemark-entries'.") 144 | (face :initarg :face 145 | :initform linemark-funny-face 146 | ; Something created w/ defface is not a face in XEmacs. 147 | ; :type (or null face) 148 | :documentation "Default face used to create new `linemark-entries'.") 149 | (active :initarg :active 150 | :type boolean 151 | :initform t 152 | :documentation "Track if these marks are active or not.")) 153 | "Track a common group of `linemark-entries'.") 154 | 155 | ;;; Functions 156 | ;; 157 | (defvar linemark-groups nil 158 | "List of groups we need to track.") 159 | 160 | (defun linemark-create-group (name &optional defaultface) 161 | "*Obsolete*. 162 | Create a group object for tracking linemark entries. 163 | Do not permit multiple groups with the same NAME. 164 | Optional argument DEFAULTFACE is the :face slot for the object." 165 | (linemark-new-group 'linemark-group name :face defaultface) 166 | ) 167 | 168 | (defun linemark-new-group (class name &rest args) 169 | "Create a new linemark group based on the linemark CLASS. 170 | Give this group NAME. ARGS are slot/value pairs for 171 | the new instantiation." 172 | (let ((newgroup nil) 173 | (foundgroup nil) 174 | (lmg linemark-groups)) 175 | ;; Find an old group. 176 | (while (and (not foundgroup) lmg) 177 | (if (string= name (object-name-string (car lmg))) 178 | (setq foundgroup (car lmg))) 179 | (setq lmg (cdr lmg))) 180 | ;; Which group to use. 181 | (if foundgroup 182 | ;; Recycle the old group 183 | (setq newgroup foundgroup) 184 | ;; Create a new group 185 | (setq newgroup (apply 'make-instance class name args)) 186 | (setq linemark-groups (cons newgroup linemark-groups))) 187 | ;; Return the group 188 | newgroup)) 189 | 190 | (defun linemark-at-point (&optional pos group) 191 | "Return the current variable `linemark-entry' at point. 192 | Optional POS is the position to check which defaults to point. 193 | If GROUP, then make sure it also belongs to GROUP." 194 | (if (not pos) (setq pos (point))) 195 | (let ((o (linemark-overlays-at pos)) 196 | (found nil)) 197 | (while (and o (not found)) 198 | (let ((og (linemark-overlay-get (car o) 'obj))) 199 | (if (and og (linemark-entry-child-p og)) 200 | (progn 201 | (setq found og) 202 | (if group 203 | (if (not (eq group (oref found parent))) 204 | (setq found nil))))) 205 | (setq o (cdr o)))) 206 | found)) 207 | 208 | (defun linemark-next-in-buffer (group &optional arg wrap) 209 | "Return the next mark in this buffer belonging to GROUP. 210 | If ARG, then find that manu marks forward or backward. 211 | Optional WRAP argument indicates that we should wrap around the end of 212 | the buffer." 213 | (if (not arg) (setq arg 1)) ;; default is one forward 214 | (let* ((entry (linemark-at-point (point) group)) 215 | (nc (if entry 216 | (if (< 0 arg) (linemark-end entry) 217 | (linemark-begin entry)) 218 | (point))) 219 | (dir (if (< 0 arg) 1 -1)) 220 | (ofun (if (> 0 arg) 221 | 'linemark-previous-overlay-change 222 | 'linemark-next-overlay-change)) 223 | (bounds (if (< 0 arg) (point-min) (point-max))) 224 | ) 225 | (setq entry nil) 226 | (catch 'moose 227 | (save-excursion 228 | (while (and (not entry) (/= arg 0)) 229 | (setq nc (funcall ofun nc)) 230 | (setq entry (linemark-at-point nc group)) 231 | (if (not entry) 232 | (if (or (= nc (point-min)) (= nc (point-max))) 233 | (if (not wrap) 234 | (throw 'moose t) 235 | (setq wrap nil ;; only wrap once 236 | nc bounds)))) 237 | ;; Ok, now decrement arg, and keep going. 238 | (if entry 239 | (setq arg (- arg dir) 240 | nc (linemark-end entry)))))) 241 | entry)) 242 | 243 | ;;; Methods that make things go 244 | ;; 245 | (defmethod linemark-add-entry ((g linemark-group) &rest args) 246 | "Add a `linemark-entry' to G. 247 | It will be at location specified by :filename and :line, and :face 248 | which are property list entries in ARGS. 249 | Call the new entrie's activate method." 250 | (let ((file (plist-get args :filename)) 251 | (line (plist-get args :line)) 252 | (face (plist-get args :face))) 253 | (if (not file) 254 | (progn 255 | (setq file (buffer-file-name)) 256 | (if file 257 | (setq file (expand-file-name file)) 258 | (setq file (buffer-name))))) 259 | (when (not line) 260 | (setq line (count-lines (point-min) (point))) 261 | (if (bolp) (setq line (1+ line)))) 262 | (setq args (plist-put args :filename file)) 263 | (setq args (plist-put args :line line)) 264 | (let ((new-entry (apply 'linemark-new-entry g args))) 265 | (oset new-entry parent g) 266 | (oset new-entry face (or face (oref g face))) 267 | (oset g marks (cons new-entry (oref g marks))) 268 | (if (oref g active) 269 | (linemark-display new-entry t)) 270 | new-entry) 271 | )) 272 | 273 | (defmethod linemark-new-entry ((g linemark-group) &rest args) 274 | "Create a new entry for G using init ARGS." 275 | (let ((f (plist-get args :filename)) 276 | (l (plist-get args :line))) 277 | (apply 'linemark-entry (format "%s %d" f l) 278 | args))) 279 | 280 | (defmethod linemark-display ((g linemark-group) active-p) 281 | "Set object G to be active or inactive." 282 | (mapc (lambda (g) (linemark-display g active-p)) (oref g marks)) 283 | (oset g active active-p)) 284 | 285 | (defmethod linemark-display ((e linemark-entry) active-p) 286 | "Set object E to be active or inactive." 287 | (if active-p 288 | (with-slots ((file filename)) e 289 | (if (oref e overlay) 290 | ;; Already active 291 | nil 292 | (let ((buffer)) 293 | (if (get-file-buffer file) 294 | (setq buffer (get-file-buffer file)) 295 | (setq buffer (get-buffer file))) 296 | (if buffer 297 | (with-current-buffer buffer 298 | (save-excursion 299 | (goto-char (point-min)) 300 | (forward-line (1- (oref e line))) 301 | (oset e overlay 302 | (linemark-make-overlay (point) 303 | (save-excursion 304 | (end-of-line) (point)) 305 | (current-buffer))) 306 | (with-slots (overlay) e 307 | (linemark-overlay-put overlay 'face (oref e face)) 308 | (linemark-overlay-put overlay 'obj e) 309 | (linemark-overlay-put overlay 'tag 'linemark)))))))) 310 | ;; Not active 311 | (with-slots (overlay) e 312 | (if overlay 313 | (progn 314 | (condition-case nil 315 | ;; During development of linemark programs, this is helpful 316 | (linemark-delete-overlay overlay) 317 | (error nil)) 318 | (oset e overlay nil)))))) 319 | 320 | (defmethod linemark-delete ((g linemark-group)) 321 | "Remove group G from linemark tracking." 322 | (mapc 'linemark-delete (oref g marks)) 323 | (setq linemark-groups (delete g linemark-groups))) 324 | 325 | (defmethod linemark-delete ((e linemark-entry)) 326 | "Remove entry E from it's parent group." 327 | (with-slots (parent) e 328 | (oset parent marks (delq e (oref parent marks))) 329 | (linemark-display e nil))) 330 | 331 | (defmethod linemark-begin ((e linemark-entry)) 332 | "Position at the start of the entry E." 333 | (with-slots (overlay) e 334 | (linemark-overlay-start overlay))) 335 | 336 | (defmethod linemark-end ((e linemark-entry)) 337 | "Position at the end of the entry E." 338 | (with-slots (overlay) e 339 | (linemark-overlay-end overlay))) 340 | 341 | ;;; Trans buffer tracking 342 | ;; 343 | ;; This section sets up a find-file-hook and a kill-buffer-hook 344 | ;; so that marks that aren't displayed (because the buffer doesn't 345 | ;; exist) are displayed when said buffer appears, and that overlays 346 | ;; are removed when the buffer buffer goes away. 347 | 348 | (defun linemark-find-file-hook () 349 | "Activate all marks which can benifit from this new buffer." 350 | (mapcar (lambda (g) (linemark-display g t)) linemark-groups)) 351 | 352 | (defun linemark-kill-buffer-hook () 353 | "Deactivate all entries in the current buffer." 354 | (let ((o (linemark-overlays-in (point-min) (point-max))) 355 | (to nil)) 356 | (while o 357 | (setq to (linemark-overlay-get (car o) 'obj)) 358 | (if (and to (linemark-entry-child-p to)) 359 | (linemark-display to nil)) 360 | (setq o (cdr o))))) 361 | 362 | (add-hook 'find-file-hooks 'linemark-find-file-hook) 363 | (add-hook 'kill-buffer-hook 'linemark-kill-buffer-hook) 364 | 365 | ;;; Demo mark tool: Emulate MS Visual Studio bookmarks 366 | ;; 367 | (defvar viss-bookmark-group (linemark-new-group 'linemark-group "viss") 368 | "The VISS bookmark group object.") 369 | 370 | (defun viss-bookmark-toggle () 371 | "Toggle a bookmark on the current line." 372 | (interactive) 373 | (let ((ce (linemark-at-point (point) viss-bookmark-group))) 374 | (if ce 375 | (linemark-delete ce) 376 | (linemark-add-entry viss-bookmark-group)))) 377 | 378 | (defun viss-bookmark-next-buffer () 379 | "Move to the next bookmark in this buffer." 380 | (interactive) 381 | (let ((n (linemark-next-in-buffer viss-bookmark-group 1 t))) 382 | (if n 383 | (progn 384 | (goto-char (point-min)) 385 | (forward-line (1- (oref n line)))) 386 | (ding)))) 387 | 388 | (defun viss-bookmark-prev-buffer () 389 | "Move to the next bookmark in this buffer." 390 | (interactive) 391 | (let ((n (linemark-next-in-buffer viss-bookmark-group -1 t))) 392 | (if n 393 | (progn 394 | (goto-char (point-min)) 395 | (forward-line (1- (oref n line)))) 396 | (ding)))) 397 | 398 | (defun viss-bookmark-clear-all-buffer () 399 | "Clear all bookmarks in this buffer." 400 | (interactive) 401 | (mapcar (lambda (e) 402 | (if (or (string= (oref e filename) (buffer-file-name)) 403 | (string= (oref e filename) (buffer-name))) 404 | (linemark-delete e))) 405 | (oref viss-bookmark-group marks))) 406 | 407 | ;; These functions only sort of worked and were not really useful to me. 408 | ;; 409 | ;;(defun viss-bookmark-next () 410 | ;; "Move to the next bookmark." 411 | ;; (interactive) 412 | ;; (let ((c (linemark-at-point (point) viss-bookmark-group)) 413 | ;; (n nil)) 414 | ;; (if c 415 | ;; (let ((n (member c (oref viss-bookmark-group marks)))) 416 | ;; (if n (setq n (car (cdr n))) 417 | ;; (setq n (car (oref viss-bookmark-group marks)))) 418 | ;; (if n (goto-line (oref n line)) (ding))) 419 | ;; ;; if no current mark, then just find a local one. 420 | ;; (viss-bookmark-next-buffer)))) 421 | ;; 422 | ;;(defun viss-bookmark-prev () 423 | ;; "Move to the next bookmark." 424 | ;; (interactive) 425 | ;; (let ((c (linemark-at-point (point) viss-bookmark-group)) 426 | ;; (n nil)) 427 | ;; (if c 428 | ;; (let* ((marks (oref viss-bookmark-group marks)) 429 | ;; (n (member c marks))) 430 | ;; (if n 431 | ;; (setq n (- (- (length marks) (length n)) 1)) 432 | ;; (setq n (car marks))) 433 | ;; (if n (goto-line (oref n line)) (ding))) 434 | ;; ;; if no current mark, then just find a local one. 435 | ;; (viss-bookmark-prev-buffer)))) 436 | ;; 437 | ;;(defun viss-bookmark-clear-all () 438 | ;; "Clear all viss bookmarks." 439 | ;; (interactive) 440 | ;; (mapcar (lambda (e) (linemark-delete e)) 441 | ;; (oref viss-bookmark-group marks))) 442 | ;; 443 | 444 | ;;;###autoload 445 | (defun enable-visual-studio-bookmarks () 446 | "Bind the viss bookmark functions to F2 related keys. 447 | \\ 448 | \\[viss-bookmark-toggle] - To=ggle a bookmark on this line. 449 | \\[viss-bookmark-next-buffer] - Move to the next bookmark. 450 | \\[viss-bookmark-prev-buffer] - Move to the previous bookmark. 451 | \\[viss-bookmark-clear-all-buffer] - Clear all bookmarks." 452 | (interactive) 453 | (define-key global-map [(f2)] 'viss-bookmark-toggle) 454 | (define-key global-map [(shift f2)] 'viss-bookmark-prev-buffer) 455 | (define-key global-map [(control f2)] 'viss-bookmark-next-buffer) 456 | (define-key global-map [(control shift f2)] 'viss-bookmark-clear-all-buffer) 457 | ) 458 | 459 | (provide 'linemark) 460 | 461 | ;;; linemark.el ends here 462 | -------------------------------------------------------------------------------- /matlab-publish.el: -------------------------------------------------------------------------------- 1 | ;;; matlab-publish.el --- Utilities for editing MATLAB files for publishing 2 | 3 | ;; Copyright (C) 2009 Uwe Brauer 4 | 5 | ;; Author: Uwe Brauer oub@mat.ucm.es 6 | ;; Maintainer: Uwe Brauer oub@mat.ucm.es 7 | ;; Created: 25 Feb 2009 8 | ;; Version: 1.0 9 | ;; Keywords: 10 | 11 | 12 | ;; This program is free software; you can redistribute it and/or modify 13 | ;; it under the terms of the GNU General Public License as published by 14 | ;; the Free Software Foundation; either version 1, or (at your option) 15 | ;; any later version. 16 | 17 | ;; This program is distributed in the hope that it will be useful, 18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | ;; GNU General Public License for more details. 21 | 22 | ;; A copy of the GNU General Public License can be obtained from this 23 | ;; program's author (send electronic mail to oub@mat.ucm.es) or from 24 | ;; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 25 | ;; 02139, USA. 26 | 27 | ;; LCD Archive Entry: 28 | ;; my-pub|Uwe Brauer|oub@mat.ucm.es 29 | ;; | 30 | ;; |$Date$|$Revision$|~/packages/my-pub.el 31 | 32 | ;;; Commentary: 33 | 34 | ;;{{{Change log: 35 | 36 | ;; $Id$ 37 | ;; $Log$ 38 | ;; Revision 1.9 2009/03/08 09:38:31 oub 39 | ;; * matlab-publish.el (matlab-select-environment): change function 40 | ;; slightly 41 | ;; (matlab-insert-section): new function 42 | ;; 43 | ;; Revision 1.8 2009/03/07 13:54:57 oub 44 | ;; (matlab-write-region-novisit): New function 45 | ;; (matlab-publish-region-old): new function 46 | ;; (matlab-publish-region): New function 47 | ;; (matlab-publish-region-latex): new function 48 | ;; (matlab-publish-region-html): new function 49 | ;; 50 | ;; Revision 1.7 2009/03/07 13:26:55 oub 51 | ;; (matlab-show-matlab-shell): New variable 52 | ;; (matlab-publish-file-latex): add 53 | ;; (if matlab-show-matlab-shell 54 | ;; (matlab-show-matlab-shell-buffer))) 55 | ;; 56 | ;; Revision 1.6 2009/03/07 11:00:04 oub 57 | ;; * matlab-publish.el (matlab-boldify): Modify the function. 58 | ;; 59 | ;; Revision 1.5 2009/03/06 14:24:47 oub 60 | ;; * matlab-publish.el (matlab-temp-region-file): new variable 61 | ;; (matlab-write-region): New function 62 | ;; 63 | ;; Revision 1.4 2009/02/26 16:18:23 oub 64 | ;; modifiy the insert functions in order that the jump to the text where 65 | ;; new stuff has to be inserted. 66 | ;; 67 | ;; Revision 1.3 2009/02/26 16:06:08 oub 68 | ;; (defun matlab-select-environment (ch) 69 | ;; (interactive "c1: title, 2: descr, 3: bold:, 4:mono, 5:pre, 6:equation, 7:list ") 70 | ;; (setq ch (downcase ch)) 71 | ;; (call-interactively (cond ((eql ch ?1) #'matlab-insert-title) 72 | ;; ((eql ch ?2) #'matlab-insert-description-text) 73 | ;; ((eql ch ?3) #'matlab-insert-bold-text) 74 | ;; ((eql ch ?4) #'matlab-insert-monospaces-text) 75 | ;; ((eql ch ?5) #'matlab-insert-preformated-text) 76 | ;; ((eql ch ?6) #'matlab-insert-equation) 77 | ;; ((eql ch ?7) #'matlab-insert-bullet-list) 78 | ;; (t (error 'args-out-of-range '(1 2 3 5 6 7 ch)))))) 79 | ;; 80 | ;; Revision 1.2 2009/02/26 11:24:17 oub 81 | ;; New functions 82 | ;; (defun matlab-insert-title () 83 | ;; 84 | ;; (defun matlab-insert-description-text () 85 | ;; 86 | ;; 87 | ;; (defun matlab-insert-bold-text () 88 | ;; 89 | ;; 90 | ;; (defun matlab-insert-monospaces-text () 91 | ;; 92 | ;; 93 | ;; 94 | ;; (defun matlab-insert-preformated-text () 95 | ;; 96 | ;; 97 | ;; (defun matlab-insert-equation () 98 | ;; 99 | ;; 100 | ;; (defun matlab-insert-bullet-list () 101 | ;; 102 | ;; Revision 1.1 2009/02/26 11:15:02 oub 103 | ;; Initial revision 104 | ;; 105 | 106 | ;;}}} 107 | 108 | ;;; Code: 109 | 110 | 111 | ;; (defun my-publish-matlab () 112 | ;; (interactive) 113 | ;; (let ((pub (file-name-nondirectory (buffer-file-name)))) 114 | ;; (let ((arg (concat "publish('" pub "','latex')"))) 115 | ;; (matlab-shell-run-command arg)))) 116 | 117 | (require 'matlab) 118 | 119 | ;; Variables 120 | (defvar matlab-temp-region-file "region.m" ;Version-1.5 121 | "*Variable for the file which saves the region for publishing.") 122 | 123 | (defvar matlab-show-matlab-shell t 124 | "* t means the matlab buffer shell is shown when running matlab.") 125 | 126 | ;; Functions 127 | (defun matlab-select-publish-form (ch) 128 | "This function allows to publish the m file, either as in LaTeX or in 129 | HTML format." 130 | (interactive "c1: LaTeX, 2: HTML ") 131 | (setq ch (downcase ch)) 132 | (call-interactively (cond ((eql ch ?1) #'matlab-publish-file-latex) 133 | ((eql ch ?2) #'matlab-publish-file-html) 134 | (t (error 'args-out-of-range '(1 2 ch)))))) 135 | 136 | (defun matlab-publish-file-latex () ;Version-1.7 137 | "Publish a matlab file in the LaTeX format." 138 | (interactive) 139 | (let ((pub (file-name-nondirectory (buffer-file-name)))) 140 | (matlab-shell-run-command (format "publish('%s','latex')" pub))) 141 | (if matlab-show-matlab-shell 142 | (matlab-show-matlab-shell-buffer))) 143 | 144 | 145 | 146 | (defun matlab-publish-file-html () ;Version-1.7 147 | (interactive) 148 | "Publish a matlab file in the html format." 149 | (let ((pub (file-name-nondirectory (buffer-file-name)))) 150 | (matlab-shell-run-command (format "publish('%s','html')" pub))) 151 | (if matlab-show-matlab-shell 152 | (matlab-show-matlab-shell-buffer))) 153 | 154 | 155 | 156 | (defun matlab-select-environment (ch) ;Version-1.9 157 | "This functions inserts structured text, which results for example 158 | in LaTeX mode in title, sections, description, boldified text, unnumbered equations and bullet list." 159 | (interactive "c1: title, 2: section, 3:descrip, 4:boldify, 5:equation, 6:list ") 160 | (setq ch (downcase ch)) 161 | (call-interactively (cond ((eql ch ?1) #'matlab-insert-title) 162 | ((eql ch ?2) #'matlab-insert-section) 163 | ((eql ch ?3) #'matlab-insert-description-text) 164 | ((eql ch ?4) #'matlab-boldify) 165 | ((eql ch ?5) #'matlab-insert-equation) 166 | ((eql ch ?6) #'matlab-insert-bullet-list) 167 | (t (error 'args-out-of-range '(1 2 3 5 6 ch)))))) 168 | 169 | 170 | (defun matlab-insert-title () 171 | (interactive) 172 | (beginning-of-buffer nil) 173 | (insert "%% TITLE\n") 174 | (previous-line 1) 175 | (forward-char 3)) 176 | 177 | (defun matlab-insert-section () ;Version-1.9 178 | (interactive) 179 | (insert "%% Section\n") 180 | (previous-line 1) 181 | (forward-char 3)) 182 | 183 | 184 | (defun matlab-insert-description-text () 185 | (interactive) 186 | (insert "%%\n") 187 | (insert "% DESCRIPTIVE TEXT\n") 188 | (previous-line 1) 189 | (forward-char 2)) 190 | 191 | 192 | 193 | (defun matlab-boldify () ;Version-1.6 194 | "Insert either \%\%\\n \% \*BOLD TEXT\*\\n or, when mark is active, 195 | surrounds region by * *." 196 | (interactive) 197 | (if (or (and (boundp 'zmacs-region-active-p) zmacs-region-active-p) 198 | (and (boundp 'transient-mark-mode) transient-mark-mode mark-active)) 199 | (save-excursion 200 | (goto-char (point)) 201 | (insert "*") 202 | (goto-char (mark)) 203 | (insert "*")) 204 | (insert "\n%%\n") 205 | (insert "% *BOLD TEXT*\n") 206 | (backward-char 2))) 207 | 208 | 209 | (defun matlab-insert-bold-text () 210 | (interactive) 211 | (insert "%%\n") 212 | (insert "% *BOLD TEXT*\n") 213 | (previous-line 1) 214 | (forward-char 2)) 215 | 216 | (defun matlab-insert-monospaces-text () 217 | (interactive) 218 | (insert "%%\n") 219 | (insert "% |MONOSPACED TEXT|\n") 220 | (previous-line 1) 221 | (forward-char 2)) 222 | 223 | 224 | (defun matlab-insert-preformated-text () 225 | (interactive) 226 | (insert "%%\n") 227 | (insert "%\n") 228 | (insert "% PREFORMATTED\n") 229 | (insert "% TEXT\n") 230 | (insert "% \n") 231 | (previous-line 3) 232 | (forward-char 3)) 233 | 234 | (defun matlab-insert-equation () 235 | (interactive) 236 | (insert "%%\n") 237 | (insert "% \n") 238 | (insert "% $$e^{\pi i} + 1 = 0$$\n") 239 | (insert "% \n") 240 | (previous-line 2) 241 | (forward-char 4)) 242 | 243 | 244 | (defun matlab-insert-bullet-list () 245 | (interactive) 246 | (insert "%%\n") 247 | (insert "% \n") 248 | (insert "% * ITEM1\n") 249 | (insert "% * ITEM2\n") 250 | (insert "% \n") 251 | (previous-line 3) 252 | (forward-char 4)) 253 | 254 | 255 | 256 | 257 | (defun matlab-write-region (start end) ;Version-1.5 258 | (interactive "r") 259 | (write-region start end (expand-file-name matlab-temp-region-file) nil nil nil nil) 260 | (find-file matlab-temp-region-file)) 261 | 262 | 263 | (defun matlab-write-region-novisit (start end) 264 | (interactive "r") 265 | (write-region start end (expand-file-name matlab-temp-region-file) nil nil nil nil)) 266 | 267 | 268 | 269 | 270 | (defun matlab-publish-region-old (ch) ;Version-1.8 271 | (interactive "c1: LaTeX, 2: HTML ") 272 | (setq ch (downcase ch)) 273 | (matlab-write-region-novisit (region-beginning) (region-end)) 274 | (call-interactively (cond ((eql ch ?1) #'matlab-publish-region-latex) 275 | ((eql ch ?2) #'matlab-publish-region-html) 276 | (t (error 'args-out-of-range '(1 2 ch)))))) 277 | 278 | 279 | (defun matlab-publish-region (start end ch) ;Version-1.8 280 | (interactive "r\nc1: LaTeX, 2: HTML ") 281 | (setq ch (downcase ch)) 282 | (write-region start end (expand-file-name matlab-temp-region-file) nil nil nil nil) 283 | (call-interactively (cond ((eql ch ?1) #'matlab-publish-region-latex) 284 | ((eql ch ?2) #'matlab-publish-region-html) 285 | (t (error 'args-out-of-range '(1 2 ch)))))) 286 | 287 | 288 | 289 | (defun matlab-publish-region-latex () ;Version-1.8 290 | (interactive) 291 | (matlab-shell-run-command (format "publish('%s','latex')" matlab-temp-region-file)) 292 | (if matlab-show-matlab-shell 293 | (matlab-show-matlab-shell-buffer))) 294 | 295 | 296 | 297 | (defun matlab-publish-region-html () ;Version-1.8 298 | (interactive) 299 | (matlab-shell-run-command (format "publish('%s','html')" matlab-temp-region-file)) 300 | (if matlab-show-matlab-shell 301 | (matlab-show-matlab-shell-buffer))) 302 | 303 | 304 | 305 | 306 | (provide 'matlab-publish) 307 | 308 | ;;; MY-PUB.EL ends here 309 | 310 | ;; (defvar isp "hallo" 311 | ;; "*check") 312 | ;; 313 | ;; (when (string-match isp "hallo")) 314 | ;; (message "it works")) -------------------------------------------------------------------------------- /mlint.el: -------------------------------------------------------------------------------- 1 | ;;; mlint.el --- run mlint in a MATLAB buffer 2 | 3 | ;; Author: Eric M. Ludlam 4 | ;; Maintainer: Eric M. Ludlam 5 | ;; Created: June 25, 2002 6 | ;; Version: 7 | 8 | (defvar mlint-version "1.3.1" 9 | "The current version of mlint minor mode.") 10 | 11 | ;; Copyright (C) 2002-2005, 2013, 2014 The MathWorks Inc. 12 | ;; 13 | ;; This program is free software; you can redistribute it and/or modify 14 | ;; it under the terms of the GNU General Public License as published by 15 | ;; the Free Software Foundation; either version 2, or (at your option) 16 | ;; any later version. 17 | ;; 18 | ;; This program is distributed in the hope that it will be useful, 19 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | ;; GNU General Public License for more details. 22 | ;; 23 | ;; You should have received a copy of the GNU General Public License 24 | ;; along with GNU Emacs; see the file COPYING. If not, write to 25 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 26 | 27 | ;;; Commentary: 28 | ;; 29 | ;; Run mlint, and highlight the problems in the buffer. 30 | ;; 31 | 32 | (require 'matlab) 33 | (require 'linemark) 34 | 35 | ;;; Code: 36 | (defvar mlint-platform 37 | ;; xxx which matlab 38 | ;; MATLABROOT/bin/util/arch.sh (or arch.bat) 39 | (cond ((eq system-type 'darwin) 40 | (if (string-match "i386" system-configuration) 41 | (let ((mt (getenv "MACHTYPE"))) 42 | (if (and (stringp mt) (string= "x86_32" mt)) 43 | ;; This hack is bad since an Emacs started from 44 | ;; the doc doesn't have this variable, thus by defaulting 45 | ;; to checking the 32 bit (not common anymore) version, 46 | ;; we'll get the right answer most of the time. 47 | "maci" "maci64")) 48 | "mac")) 49 | ((eq system-type 'gnu/linux) 50 | (cond ((string-match "64\\|i686" system-configuration) 51 | "glnxa64") 52 | (t "glnx86"))) 53 | ((eq system-type 'solaris) 54 | "sol2") 55 | ((eq system-type 'hpux) 56 | "hpux") 57 | ((eq system-type 'windows-nt) 58 | ;; Thought about checking the env PROCESSOR_ARCHITEW6432, 59 | ;; but this said AMD on my Intel, which seemed suspicious. 60 | (let ((proc (getenv "PROCESSOR_IDENTIFIER"))) 61 | (if (and (stringp proc) (string-match "64" proc)) 62 | "win64" 63 | "win32"))) 64 | (t "unknown")) 65 | "Platform we are running mlint on.") 66 | 67 | (defcustom mlint-calculate-cyclic-complexity-flag nil 68 | "*Non-nil means to collect cyclic complexity values." 69 | :group 'mlint 70 | :type 'boolean) 71 | 72 | (defvar mlint-symtab-info nil 73 | "Symbol Table collected from highlighting cross function variables. 74 | Each entry in the symtab is at an index indicating the line it occurs on. 75 | Each entry is of the form: 76 | ( \"FUNCTION-NAME\" PARENT-IDX ( LINENO . COLNO ) ...) 77 | and ... is a list of cross-function variable usages.") 78 | (make-variable-buffer-local 'mlint-symtab-info) 79 | 80 | (defun mlint-programs-set-fcn (&optional symbol value) 81 | "The :set function for `matlab-programs'. 82 | SYMBOL is the variable being set. VALUE is the new value." 83 | (condition-case nil 84 | (custom-set-default symbol value) 85 | (error (set symbol value))) 86 | (mlint-reset-program)) 87 | 88 | (defvar mlint-program-selection-fcn nil 89 | "Function use to specify the `mlint-program' for the current buffer.") 90 | 91 | (defvar mlint-program nil 92 | "Program to run for MLint. 93 | This value can be automatically set by `mlint-programs'.") 94 | 95 | (defun mlint-reset-program () 96 | "Reset `mlint-program'." 97 | (setq mlint-program 98 | (let ((mlp mlint-programs) 99 | (ans nil)) 100 | (while (and mlp (not ans)) 101 | (cond ((null (car mlp)) 102 | nil) 103 | ((file-executable-p (car mlp)) 104 | (setq ans (car mlp))) 105 | ((executable-find (car mlp)) 106 | (setq ans (executable-find (car mlp)))) 107 | (t nil)) 108 | (setq mlp (cdr mlp))) 109 | ans))) 110 | 111 | (defcustom mlint-programs (list 112 | "mlint" 113 | (concat mlint-platform "/mlint")) 114 | "*List of possible locations of the mlint program." 115 | :group 'mlint 116 | :type '(repeat (file :tag "MLint Program: ")) 117 | :set 'mlint-programs-set-fcn) 118 | 119 | (defcustom mlint-flags '("-all" "-id") ; "-fix") % Need to support this output 120 | "*List of flags passed to mlint." 121 | :group 'mlint 122 | :type '(repeat (string :tag "Option: "))) 123 | 124 | (defconst mlint-output-regex 125 | "^L \\([0-9]+\\) (C \\([-0-9]+\\)): \\(\\w+\\): \\([^\n]+\\)" 126 | "Regular expression for collecting mlint output.") 127 | 128 | (defconst mlint-symtab-line-regex 129 | ;; serial number name parent 130 | (concat "^ *\\([0-9]+\\) +\\([a-zA-Z0-9_]+\\) +\\([0-9]+\\)" 131 | ;; cross-function variable function-line function-column 132 | " +\\(V +CH\\(Set\\|Used\\).*\\|F.* \\([0-9]+\\)/\\([0-9]+\\)\\)$") 133 | "Regular expression for mlint symbol table line.") 134 | 135 | (defcustom mlint-verbose nil 136 | "*Non nil if command `mlint-minor-mode' should display messages while running." 137 | :group 'mlint 138 | :type 'boolean) 139 | 140 | (defcustom mlint-scan-for-fixes-flag t 141 | "Non-nil means that we should scan mlint output for things to fix. 142 | Scanning using `mlint-error-fix-alist' can slow things down, and may 143 | be cause for being turned off in a buffer." 144 | :group 'mlint 145 | :type 'boolean) 146 | (make-variable-buffer-local 'mlint-scan-for-fixes-flag) 147 | 148 | (defvar mlint-error-id-fix-alist 149 | '( 150 | ( AND2 . mlint-lm-entry-logicals) 151 | ( OR2 . mlint-lm-entry-logicals) 152 | ( INUSD . mlint-lm-entry-unused-argument ) 153 | ( NOPRT . mlint-lm-quiet ) 154 | ( NOSEM . mlint-lm-delete-focus ) 155 | ( NOCOM . mlint-lm-delete-focus ) 156 | ( ST2NM . mlint-lm-str2num ) 157 | ( FDEPR . mlint-lm-entry-depricated ) 158 | ) 159 | "List of warning IDs and auto-fix functions. 160 | If the CAR of an association matches an error id then the linemark entry 161 | created is of the class in CDR.") 162 | 163 | (defun mlint-column-output (string) 164 | "Convert the mlint column output to a cons pair. 165 | \(COLSTART . COLEND). 166 | Argument STRING is the text to interpret." 167 | (save-match-data 168 | (if (string-match "\\([0-9]+\\)-\\([0-9]+\\)" string) 169 | (cons (string-to-int (match-string 1 string)) 170 | (string-to-int (match-string 2 string))) 171 | (let ((i (string-to-int string))) 172 | (cons i i))))) 173 | 174 | (defun mlint-run (&optional buffer) 175 | "Run mlint on BUFFER and return a list of issues. 176 | If BUFFER is nil, use the current buffer." 177 | (when (and (file-exists-p (buffer-file-name)) mlint-program) 178 | (let* ((fn (buffer-file-name (current-buffer))) 179 | (buffer-mlint-program mlint-program) 180 | (dd default-directory) 181 | (show-mlint-warnings matlab-show-mlint-warnings) 182 | (highlight-cross-function-variables 183 | (and matlab-functions-have-end 184 | matlab-highlight-cross-function-variables)) 185 | (flags (let ((tmp (if matlab-show-mlint-warnings mlint-flags nil))) 186 | (setq tmp 187 | (if highlight-cross-function-variables 188 | (cons "-edit" tmp) 189 | tmp)) 190 | (setq tmp 191 | (if mlint-calculate-cyclic-complexity-flag 192 | (cons "-cyc" tmp) 193 | tmp)) 194 | tmp)) 195 | (errors nil) 196 | (n nil) 197 | (symtab nil)) 198 | (save-excursion 199 | (set-buffer (get-buffer-create "*M-Lint*")) 200 | (erase-buffer) 201 | (when mlint-verbose (message "Running mlint...")) 202 | 203 | (apply 'call-process buffer-mlint-program nil (current-buffer) nil 204 | (append flags (list fn))) 205 | 206 | (when mlint-verbose (message "Running mlint...done")) 207 | (goto-char (point-min)) 208 | (when highlight-cross-function-variables 209 | (when (not (re-search-forward mlint-output-regex nil t)) 210 | (goto-char (point-max))) 211 | (when (re-search-backward "^ *\\([0-9]+\\)" nil t) 212 | (goto-char (point-min)) 213 | (setq n (1+ (string-to-int (match-string 1)))) 214 | (setq symtab (make-vector n nil)) 215 | (while (re-search-forward mlint-symtab-line-regex nil t) 216 | (let ((name (match-string 2)) 217 | (parent-index (string-to-int (match-string 3))) 218 | (column (match-string 7))) 219 | (if column ;; line defines a function 220 | (aset symtab (string-to-int (match-string 1)) 221 | (list name 222 | (when (/= parent-index 0) parent-index) 223 | (cons (string-to-int (match-string 6)) 224 | (string-to-int column)))) 225 | (let ((parent (cddr (aref symtab parent-index)))) 226 | (if parent 227 | (rplacd parent (cons name (cdr parent)))))))))) 228 | (when show-mlint-warnings 229 | (while (re-search-forward mlint-output-regex nil t) 230 | (setq errors (cons 231 | (list (string-to-int (match-string 1)) 232 | (mlint-column-output (match-string 2)) 233 | (match-string 4) 234 | "" ; this was the warning code (level) 235 | (match-string 3) 236 | ) 237 | errors)))) 238 | ) 239 | (mlint-clear-nested-function-info-overlays) 240 | (setq mlint-symtab-info symtab) 241 | (when (and highlight-cross-function-variables (integerp n)) 242 | ;; Then set up new overlays for cross-function variables 243 | ;; and nested functions. 244 | (save-excursion 245 | (while (> n 0) 246 | (setq n (1- n)) 247 | (let ((entry (aref mlint-symtab-info n))) 248 | (if entry 249 | (let ((where (caddr entry))) 250 | (goto-line (car where)) 251 | (forward-char (1- (cdr where))) 252 | (re-search-backward "function\\b") 253 | (setq where (point)) 254 | (matlab-forward-sexp) 255 | (if (cadr entry) ; nested 256 | (linemark-overlay-put 257 | (linemark-make-overlay where (point)) 258 | 'nested-function t)) 259 | (if (cdddr entry) 260 | (linemark-overlay-put 261 | (linemark-make-overlay where (point)) 262 | 'cross-function-variables 263 | (concat 264 | "\\b\\(" 265 | (mapconcat '(lambda (x) x) (cdddr entry) "\\|") 266 | "\\)\\b"))))))))) 267 | errors 268 | ))) 269 | 270 | (defclass mlint-lm-group (linemark-group) 271 | () 272 | "Group of linemarks for mlint.") 273 | 274 | (defclass mlint-lm-entry (linemark-entry) 275 | ((column :initarg :column 276 | :type integer 277 | :documentation 278 | "The column on which the warning occurs.") 279 | (column-end :initarg :column-end 280 | :type integer 281 | :documentation 282 | "The column on which the warning ends.") 283 | (coverlay :type linemark-overlay 284 | :documentation 285 | "Overlay used for the specific part of the line at issue.") 286 | (warning :initarg :warning 287 | :type string 288 | :documentation 289 | "The error message created by mlint on this line.") 290 | (warningid :initarg :warningid 291 | :type symbol 292 | :documentation 293 | "The error id provided by mlint. 294 | Warning ID's won't change between releases, unlike the warning messages.") 295 | (warningcode :initarg :warningcode 296 | :type symbol 297 | :initform 'minor 298 | :documentation 299 | "mlint return code for this type of warning.") 300 | (fixable-p :initform nil 301 | :allocation :class 302 | :type boolean 303 | :documentation 304 | "Can this class auto-fix the problem?") 305 | (fix-description :initform nil 306 | :allocation :class 307 | :type (or string null) 308 | :documentation 309 | "Description of how the fix will effect the buffer.") 310 | ) 311 | "A linemark entry.") 312 | 313 | (defun mlint-linemark-create-group () 314 | "Create a group object for tracking linemark entries. 315 | Do not permit multiple groups with the same name." 316 | (let* ((name "mlint") 317 | (newgroup (mlint-lm-group name :face 'linemark-go-face)) 318 | (foundgroup nil) 319 | (lmg linemark-groups)) 320 | (while (and (not foundgroup) lmg) 321 | (if (string= name (object-name-string (car lmg))) 322 | (setq foundgroup (car lmg))) 323 | (setq lmg (cdr lmg))) 324 | (if foundgroup 325 | (setq newgroup foundgroup) 326 | (setq linemark-groups (cons newgroup linemark-groups)) 327 | newgroup))) 328 | 329 | (defvar mlint-mark-group (mlint-linemark-create-group) 330 | "Group of marked lines for mlint.") 331 | 332 | (defun mlint-warningid->class (warningid) 333 | "For a given WARNINGID, return a class for that warning. 334 | Different warnings are handled by different classes." 335 | (if mlint-scan-for-fixes-flag 336 | (let ((al mlint-error-id-fix-alist)) 337 | (while (and al 338 | (not (eq (car (car al)) warningid)) 339 | ) 340 | (setq al (cdr al))) 341 | (or (cdr (car al)) 'mlint-lm-entry)) 342 | 'mlint-lm-entry)) 343 | 344 | (defmethod linemark-new-entry ((g mlint-lm-group) &rest args) 345 | "Add a `linemark-entry' to G. 346 | It will be at location FILE and LINE, and use optional FACE. 347 | Call the new entrie's activate method." 348 | (let* ((f (plist-get args :filename)) 349 | (l (plist-get args :line)) 350 | (wc (plist-get args :warningcode)) 351 | (c (mlint-warningid->class (plist-get args :warningid))) 352 | ) 353 | (when (stringp f) (setq f (file-name-nondirectory f))) 354 | (apply c (format "%s %d" f l) args) 355 | )) 356 | 357 | (defun mlint-end-of-something () 358 | "Move cursor to the end of whatever the cursor is on." 359 | (cond ((looking-at "\\w\\|\\s(") 360 | (forward-sexp 1)) 361 | ((looking-at "\\s.") 362 | (skip-syntax-forward ".")) 363 | (t (error nil)))) 364 | 365 | (defmethod linemark-display ((e mlint-lm-entry) active-p) 366 | "Set object E to be active." 367 | ;; A bug in linemark prevents individual entry colors. 368 | ;; Fix the color here. 369 | (let ((wc (oref e warningcode))) 370 | (oset e :face 371 | (cond ((eq wc 'major) 'linemark-stop-face) 372 | ((eq wc 'medium) 'linemark-caution-face) 373 | (t 'linemark-go-face)))) 374 | ;; Call our parent method 375 | (call-next-method) 376 | ;; Add highlight area 377 | (if active-p 378 | (when (and (not (slot-boundp e 'coverlay)) 379 | (slot-boundp e 'overlay) 380 | (oref e overlay)) 381 | (with-slots (overlay column column-end warning) e 382 | (let ((warntxt 383 | (if (mlint-is-fixable e) 384 | (concat warning "\nC-c , f to " 385 | (oref e fix-description)) 386 | warning))) 387 | ;; We called super first, so this should be an active overlay. 388 | (linemark-overlay-put overlay 'local-map mlint-overlay-map) 389 | (linemark-overlay-put overlay 'help-echo warntxt) 390 | ;; Now, if we have some column data, lets put more highlighting on. 391 | (save-excursion 392 | (set-buffer (linemark-overlay-buffer overlay)) 393 | (goto-char (linemark-overlay-start overlay)) 394 | (condition-case nil 395 | (forward-char (1- column)) 396 | ;;(move-to-column (1- column)) 397 | (error nil)) 398 | (oset e coverlay (linemark-make-overlay 399 | (point) 400 | (progn 401 | (beginning-of-line) 402 | (forward-char column-end) 403 | ;(move-to-column column-end) 404 | (point)) 405 | (current-buffer))) 406 | (with-slots (coverlay) e 407 | (linemark-overlay-put coverlay 'face 'linemark-funny-face) 408 | (linemark-overlay-put coverlay 'obj e) 409 | (linemark-overlay-put coverlay 'tag 'mlint) 410 | (linemark-overlay-put coverlay 'help-echo warntxt) 411 | ) 412 | )))) 413 | ;; Delete our spare overlay 414 | (when (slot-boundp e 'coverlay) 415 | (with-slots (coverlay) e 416 | (when coverlay 417 | (condition-case nil 418 | (linemark-delete-overlay coverlay) 419 | (error nil)) 420 | (slot-makeunbound e 'coverlay))) 421 | ))) 422 | 423 | (defmethod mlint-is-fixable ((e mlint-lm-entry)) 424 | "Return non-nil if this entry can be automatically fixed." 425 | (oref-default e fixable-p)) 426 | 427 | (defmethod mlint-fix-entry :AFTER ((e mlint-lm-entry)) 428 | "Stuff to do after a warning is considered fixed. 429 | Subclasses fulfill the duty of actually fixing the code." 430 | (linemark-display e nil) 431 | (linemark-delete e)) 432 | 433 | (defmethod mlint-fix-entry ((e mlint-lm-entry)) 434 | "This entry cannot fix warnings, so throw an error. 435 | Subclasses fulfill the duty of actually fixing the code." 436 | (error "Don't know how to fix warning")) 437 | 438 | ;;; Specialized classes 439 | ;; 440 | 441 | (defclass mlint-lm-delete-focus (mlint-lm-entry) 442 | ((fixable-p :initform t) 443 | (fix-description :initform "Delete the offending characters.") 444 | ) 445 | "Specialized entry for deleting the higlighted entry.") 446 | 447 | (defmethod mlint-fix-entry ((ent mlint-lm-delete-focus)) 448 | "Add semi-colon to end of this line." 449 | (save-excursion 450 | (goto-line (oref ent line)) 451 | (let* ((s (progn (move-to-column (1- (oref ent column))) (point))) 452 | (e (progn (move-to-column (oref ent column-end)) (point))) 453 | ) 454 | (goto-char s) 455 | (delete-region (point) e) 456 | (point) 457 | )) 458 | ) 459 | 460 | (defclass mlint-lm-replace-focus (mlint-lm-delete-focus) 461 | ((fix-description :initform "Replace the offending symbol with ") 462 | (new-text :initform "") 463 | ) 464 | "Class which can replace the focus area." 465 | :abstract t) 466 | 467 | (defmethod initialize-instance :AFTER ((this mlint-lm-replace-focus) 468 | &rest fields) 469 | "Calculate the new fix description for THIS. 470 | Optional argument FIELDS are the initialization arguments." 471 | ;; After basic initialization, update the fix description. 472 | (oset this fix-description (concat (oref mlint-lm-replace-focus fix-description) 473 | (oref this new-text)))) 474 | 475 | (defmethod mlint-fix-entry ((ent mlint-lm-replace-focus)) 476 | "Replace the focus area with :new-text" 477 | (let ((pos (call-next-method))) 478 | (save-excursion 479 | (goto-char (point)) 480 | (insert (oref ent new-text))))) 481 | 482 | (defclass mlint-lm-str2num (mlint-lm-replace-focus) 483 | ((new-text :initform "str2double")) 484 | "Replace str2num with str2double") 485 | 486 | (defclass mlint-lm-entry-depricated (mlint-lm-replace-focus) 487 | () 488 | "Entry for anything that is depricated. 489 | Extracts the replacement for the depricated symbol from the warning message.") 490 | 491 | (defmethod initialize-instance :AFTER ((this mlint-lm-entry-depricated) 492 | &rest fields) 493 | "Calculate the 'new text' for THIS instance. 494 | Optional argument FIELDS are the initialization arguments." 495 | ;; After basic initialization, update the new text field. 496 | (let* ((warn (oref this warning)) 497 | (junk (string-match "Use \\(\\w+\\) instead" warn)) 498 | (newfcn (when junk (downcase (substring warn (match-beginning 1) (match-end 1)))))) 499 | (oset this new-text newfcn) 500 | ;; After basic initialization, update the fix description. 501 | (oset this fix-description (concat (oref mlint-lm-replace-focus fix-description) 502 | newfcn)) 503 | )) 504 | 505 | (defclass mlint-lm-entry-logicals (mlint-lm-entry) 506 | ((fixable-p :initform t) 507 | (fix-description :initform "perform a replacement.") 508 | ) 509 | "Specialized logical and/or class.") 510 | 511 | (defmethod mlint-fix-entry ((ent mlint-lm-entry-logicals)) 512 | "Replace the single logical with double logical." 513 | (save-excursion 514 | (goto-line (oref ent line)) 515 | (let* ((s (progn (move-to-column (1- (oref ent column))) (point))) 516 | (e (progn (move-to-column (oref ent column-end)) (point))) 517 | (txt (buffer-substring-no-properties s e))) 518 | (goto-char s) 519 | ;; All of these are replacing single logicals with double. 520 | (insert txt))) 521 | ) 522 | 523 | (defclass mlint-lm-entry-unused-argument (mlint-lm-entry) 524 | ((fixable-p :initform t) 525 | (fix-description :initform "remove this argument.") 526 | ) 527 | "Specialized logical and/or class.") 528 | 529 | (defmethod mlint-fix-entry ((ent mlint-lm-entry-unused-argument)) 530 | "Remove the arguments." 531 | (save-excursion 532 | (goto-line (oref ent line)) 533 | (let* ((s (progn (move-to-column (1- (oref ent column))) (point))) 534 | (e (progn (move-to-column (oref ent column-end)) (point))) 535 | ) 536 | (goto-char s) 537 | (if (not (looking-at "(\\|,")) 538 | (forward-char -1)) 539 | (delete-region (point) e) 540 | )) 541 | ) 542 | 543 | (defclass mlint-lm-quiet (mlint-lm-entry) 544 | ((fixable-p :initform t) 545 | (fix-description :initform "Make sure this line prints no values.") 546 | ) 547 | "Specialized logical and/or class.") 548 | 549 | 550 | (defmethod mlint-fix-entry ((ent mlint-lm-quiet)) 551 | "Add semi-colon to end of this line." 552 | (save-excursion 553 | (matlab-end-of-command) 554 | (insert ";")) 555 | ) 556 | 557 | ;;; User functions 558 | ;; 559 | (defun mlint-highlight (err) 560 | "Setup ERR, an mlint message to be marked." 561 | (linemark-add-entry mlint-mark-group 562 | :line (nth 0 err) 563 | :column (car (nth 1 err)) 564 | :column-end (cdr (nth 1 err)) 565 | :warning (nth 2 err) 566 | ;; Old style did this lookup, but new versins of 567 | ;; MLint replace the warning code with a warning 568 | ;; ID which can instead be used for auto-fix. In addition, 569 | ;; just use the default warning code. 570 | 571 | ;;:warningcode 'minor 572 | ;; (cdr (assoc (nth 3 err) mlint-warningcode-alist)) 573 | :warningid (intern (nth 4 err)) 574 | )) 575 | 576 | (defun mlint-clear-warnings () 577 | "Unhighlight all existing mlint warnings." 578 | (interactive) 579 | (mapcar (lambda (e) 580 | (if (string= (oref e filename) (buffer-file-name)) 581 | (linemark-delete e))) 582 | (oref mlint-mark-group marks)) 583 | (if (and (boundp 'global-font-lock-mode) global-font-lock-mode 584 | (not font-lock-mode)) 585 | (font-lock-fontify-buffer))) 586 | 587 | (defun mlint-clear-nested-function-info-overlays () 588 | "Clear out any previous overlays with nested function information. 589 | This includes nested-function and cross-function-variables." 590 | (let ((overlays (linemark-overlays-in (point-min) (point-max)))) 591 | (while overlays 592 | (let* ((overlay (car overlays))) 593 | (if (or (linemark-overlay-get overlay 'cross-function-variables) 594 | (linemark-overlay-get overlay 'nested-function)) 595 | (linemark-delete-overlay overlay))) 596 | (setq overlays (cdr overlays))))) 597 | 598 | (defun mlint-clear-cross-function-variable-highlighting () 599 | "Remove cross-function-variable overalys and re-fontify buffer." 600 | (mlint-clear-nested-function-info-overlays) 601 | (if (and (boundp 'global-font-lock-mode) global-font-lock-mode 602 | (not font-lock-mode)) 603 | (font-lock-fontify-buffer))) 604 | 605 | (defun mlint-buffer () 606 | "Run mlint on the current buffer. 607 | Highlight problems and/or cross-function variables." 608 | (interactive) 609 | (when (and (buffer-file-name) mlint-program) 610 | (if (and (buffer-modified-p) 611 | (y-or-n-p (format "Save %s before linting? " 612 | (file-name-nondirectory (buffer-file-name))))) 613 | (save-buffer)) 614 | (let ((errs (mlint-run)) 615 | ) 616 | (mlint-clear-warnings) 617 | (while errs 618 | (mlint-highlight (car errs)) 619 | (setq errs (cdr errs)))))) 620 | 621 | (defun mlint-next-buffer () 622 | "Move to the next warning in this buffer." 623 | (interactive) 624 | (let ((n (linemark-next-in-buffer mlint-mark-group 1 t))) 625 | (if n 626 | (progn (goto-line (oref n line)) 627 | (message (oref n warning))) 628 | (ding)))) 629 | 630 | (defun mlint-prev-buffer () 631 | "Move to the prev warning in this buffer." 632 | (interactive) 633 | (let ((n (linemark-next-in-buffer mlint-mark-group -1 t))) 634 | (if n 635 | (progn (goto-line (oref n line)) 636 | (message (oref n warning))) 637 | (ding)))) 638 | 639 | (defun mlint-next-buffer-new () 640 | "Move to the next new warning in this buffer." 641 | (interactive) 642 | (let ((p (linemark-at-point (point) mlint-mark-group)) 643 | (n (linemark-next-in-buffer mlint-mark-group 1 t))) 644 | ;; Skip over messages that are the same as the one under point. 645 | (save-excursion 646 | (while (and n p (not (eq n p)) 647 | (string= (oref p warning) (oref n warning))) 648 | (goto-line (oref n line)) 649 | (setq n (linemark-next-in-buffer mlint-mark-group 1 t)))) 650 | (if n 651 | (progn (goto-line (oref n line)) 652 | (message (oref n warning))) 653 | (ding)))) 654 | 655 | (defun mlint-prev-buffer-new () 656 | "Move to the prev new warning in this buffer." 657 | (interactive) 658 | (let ((p (linemark-at-point (point) mlint-mark-group)) 659 | (n (linemark-next-in-buffer mlint-mark-group -1 t))) 660 | ;; Skip over messages that are the same as the one under point. 661 | (save-excursion 662 | (while (and n p (not (eq n p)) 663 | (string= (oref p warning) (oref n warning))) 664 | (goto-line (oref n line)) 665 | (setq n (linemark-next-in-buffer mlint-mark-group -1 t)))) 666 | (if n 667 | (progn (goto-line (oref n line)) 668 | (message (oref n warning))) 669 | (ding)))) 670 | 671 | (defun mlint-show-warning () 672 | "Show the warning for the current mark." 673 | (interactive) 674 | (let ((n (linemark-at-point (point) mlint-mark-group))) 675 | (if (not n) 676 | (message "No warning at point.") 677 | (message (oref n warning))))) 678 | 679 | (defun mlint-fix-warning () 680 | "Show the warning for the current mark." 681 | (interactive) 682 | (let ((n (linemark-at-point (point) mlint-mark-group))) 683 | (if (not n) 684 | (message "No warning at point.") 685 | (if (not (mlint-is-fixable n)) 686 | (message "No method for fixing this warning.") 687 | (mlint-fix-entry n))))) 688 | 689 | (defun mlint-mark-ok () 690 | "Mark this line as M-Lint Ok." 691 | (interactive) 692 | (let ((n (linemark-at-point (point) mlint-mark-group))) 693 | (if (not n) 694 | (message "No warning at point.") 695 | (let ((col (matlab-comment-on-line))) 696 | (or col (end-of-line)) 697 | (insert " %#ok") 698 | ;; Add spaces if there was a comment. 699 | (when col (insert " "))) 700 | ;; This causes inconsistencies. 701 | ;; (linemark-delete n) 702 | )) 703 | ) 704 | 705 | 706 | ;;; Define an mlinting minor mode 707 | ;; 708 | (defvar mlint-minor-mode-map 709 | (let ((map (make-sparse-keymap))) 710 | (define-key map "\C-c,n" 'mlint-next-buffer) 711 | (define-key map "\C-c,p" 'mlint-prev-buffer) 712 | (define-key map "\C-c,N" 'mlint-next-buffer-new) 713 | (define-key map "\C-c,P" 'mlint-prev-buffer-new) 714 | (define-key map "\C-c,g" 'mlint-buffer) 715 | (define-key map "\C-c,c" 'mlint-clear-warnings) 716 | (define-key map "\C-c, " 'mlint-show-warning) 717 | (define-key map "\C-c,f" 'mlint-fix-warning) 718 | (define-key map "\C-c,o" 'mlint-mark-ok) 719 | map) 720 | "Minor mode keymap used when mlinting a buffer.") 721 | 722 | (easy-menu-define 723 | mlint-minor-menu mlint-minor-mode-map "M-Lint Minor Mode Menu" 724 | '("M-Lint" 725 | ["Get M-Lint Warnings" mlint-buffer t] 726 | ["Clear M-Lint Warnings" mlint-clear-warnings t] 727 | ["Show Warning" mlint-show-warning (linemark-at-point (point) mlint-mark-group)] 728 | ["Auto Fix Warning" mlint-fix-warning 729 | (let ((w (linemark-at-point (point) mlint-mark-group))) 730 | (and mlint-scan-for-fixes-flag w (mlint-is-fixable w))) ] 731 | ["Enable Auto-fix scanning" 732 | (setq mlint-scan-for-fixes-flag (not mlint-scan-for-fixes-flag)) 733 | :style toggle :selected mlint-scan-for-fixes-flag ] 734 | ["This is Ok" mlint-mark-ok 735 | (linemark-at-point (point) mlint-mark-group) ] 736 | "--" 737 | ["Next Warning" mlint-next-buffer t] 738 | ["Previous Warning" mlint-prev-buffer t] 739 | ["Next New Warning" mlint-next-buffer-new t] 740 | ["Previous New Warning" mlint-prev-buffer-new t] 741 | )) 742 | 743 | (defvar mlint-overlay-map 744 | (let ((map (make-sparse-keymap ))) 745 | (define-key map [down-mouse-3] 'mlint-emacs-popup-kludge) 746 | (define-key map [(meta n)] 'mlint-next-buffer) 747 | (define-key map [(meta p)] 'mlint-prev-buffer) 748 | (define-key map [(control meta n)] 'mlint-next-buffer-new) 749 | (define-key map [(control meta p)] 'mlint-prev-buffer-new) 750 | (set-keymap-parent map matlab-mode-map) 751 | map) 752 | "Map used in overlays marking mlint warnings.") 753 | 754 | (defun mlint-emacs-popup-kludge (e) 755 | "Pop up a menu related to the clicked on item. 756 | Must be bound to event E." 757 | (interactive "e") 758 | (let ((repos nil) 759 | (ipos nil) 760 | (startpos (point)) 761 | ) 762 | (save-excursion 763 | (mouse-set-point e) 764 | (setq ipos (point)) 765 | (popup-menu mlint-minor-menu) 766 | (if (/= (point) ipos) (setq repos (point))) 767 | ) 768 | (when repos (goto-char repos)))) 769 | 770 | ;;;###autoload 771 | (easy-mmode-define-minor-mode mlint-minor-mode 772 | "Toggle mlint minor mode, a mode for showing mlint errors. 773 | With prefix ARG, turn mlint minor mode on iff ARG is positive. 774 | \\{mlint-minor-mode-map\\}" 775 | nil " mlint" mlint-minor-mode-map 776 | (if (and mlint-minor-mode (not (eq major-mode 'matlab-mode))) 777 | (progn 778 | (mlint-minor-mode -1) 779 | (error "M-Lint minor mode is only for MATLAB Major mode"))) 780 | (if (not mlint-minor-mode) 781 | (progn 782 | (mlint-clear-nested-function-info-overlays) 783 | (mlint-clear-warnings) 784 | (remove-hook 'after-save-hook 'mlint-buffer t) 785 | (easy-menu-remove mlint-minor-menu) 786 | ) 787 | (when mlint-program-selection-fcn 788 | (let ((ans (funcall mlint-program-selection-fcn)) 789 | ) 790 | (when ans 791 | (make-local-variable 'mlint-program) 792 | (setq mlint-program ans) 793 | ) 794 | ) 795 | ) 796 | (if (not mlint-program) 797 | (if (y-or-n-p "No MLINT program available. Configure it?") 798 | (customize-variable 'mlint-programs)) 799 | 800 | (add-hook 'after-save-hook 'mlint-buffer nil t) 801 | (easy-menu-add mlint-minor-menu mlint-minor-mode-map) 802 | (mlint-buffer)) 803 | )) 804 | 805 | (defvar mlint-minor-mode-was-enabled-before nil 806 | "Non nil if mlint is off, and it was auto-disabled.") 807 | (make-variable-buffer-local 'mlint-minor-mode-was-enabled-before) 808 | 809 | (defun mlint-ediff-metabuffer-setup-hook () 810 | "Hook run when EDiff is about to do stuff to a buffer. 811 | That buffer will be current." 812 | (when (and (eq major-mode 'matlab-mode) 813 | mlint-minor-mode) 814 | (setq mlint-minor-mode-was-enabled-before mlint-minor-mode) 815 | (mlint-minor-mode -1) 816 | )) 817 | 818 | (add-hook 'ediff-prepare-buffer-hook 'mlint-ediff-metabuffer-setup-hook) 819 | 820 | (defun mlint-ediff-cleanup-hook () 821 | "Re-enable mlint for buffers being ediffed. 822 | The buffer that was originally \"setup\" is not current, so we need to 823 | find it." 824 | (mapcar (lambda (b) 825 | (when (save-excursion 826 | (set-buffer b) 827 | (and (eq major-mode 'matlab-mode) 828 | mlint-minor-mode-was-enabled-before)) 829 | (save-excursion 830 | (set-buffer b) 831 | (mlint-minor-mode 1) 832 | (setq mlint-minor-mode-was-enabled-before nil)))) 833 | (buffer-list))) 834 | 835 | (add-hook 'ediff-cleanup-hook 'mlint-ediff-cleanup-hook) 836 | 837 | (provide 'mlint) 838 | 839 | ;;; mlint.el ends here 840 | -------------------------------------------------------------------------------- /semantic-matlab.el: -------------------------------------------------------------------------------- 1 | ;;; semantic-matlab.el --- Semantic details for MATLAB files 2 | 3 | ;;; Copyright (C) 2004, 2005, 2008, 2012, 2013 Eric M. Ludlam: The Mathworks, Inc 4 | 5 | ;; Author: Eric M. Ludlam 6 | ;; X-RCS: $Id$ 7 | 8 | ;; This file is not part of GNU Emacs. 9 | 10 | ;; This is free software; you can redistribute it and/or modify 11 | ;; it under the terms of the GNU General Public License as published by 12 | ;; the Free Software Foundation; either version 2, or (at your option) 13 | ;; any later version. 14 | 15 | ;; This software is distributed in the hope that it will be useful, 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | ;; GNU General Public License for more details. 19 | 20 | ;; You should have received a copy of the GNU General Public License 21 | ;; along with GNU Emacs; see the file COPYING. If not, write to the 22 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 23 | ;; Boston, MA 02110-1301, USA. 24 | 25 | ;;; Commentary: 26 | ;; 27 | ;; Parse a MATLAB M file for use w/ CEDET/Semantic 28 | ;; 29 | ;; The MATLAB language is pretty simple from a functional standpoint in that 30 | ;; you can only declare functions. In addition, the language itself is not 31 | ;; expressable in a yacc style grammar. It is therefore more expedient 32 | ;; to scan for regular expressions. 33 | ;; 34 | ;; Caveat: MCOS classes have property declarations. @todo - support them 35 | 36 | (require 'mode-local) 37 | (require 'semantic) 38 | (eval-and-compile 39 | (condition-case nil 40 | (require 'semantic-format) 41 | (error (require 'semantic/format))) 42 | (condition-case nil 43 | (require 'semantic-dep) 44 | (error (require 'semantic/dep))) 45 | ) 46 | (require 'matlab) 47 | (require 'semanticdb-matlab) 48 | 49 | ;;; Code: 50 | (defvar semantic-matlab-system-paths-include '("toolbox/matlab/funfun" "toolbox/matlab/general") 51 | "List of include paths under `semantic-matlab-root-directory'. 52 | These paths will be parsed recursively by semantic. Class and 53 | private directories will be omitted here.") 54 | 55 | (defvar semantic-matlab-root-directory 56 | (let* ((mlab (locate-file "matlab" exec-path)) 57 | (mlint (and (boundp 'mlint-program) 58 | mlint-program)) 59 | (exe (or mlab mlint))) 60 | (if exe 61 | (let ((dir 62 | (or (file-symlink-p exe) 63 | exe))) 64 | ;; If we have a dir, take everything until /bin as root dir. 65 | (string-match "\\(.*\\)/bin.*" dir) 66 | (match-string 1 dir)) 67 | (message "semantic-matlab: Could not find MATLAB executable in path.") 68 | nil)) 69 | "Root directory of MATLAB installation. 70 | Will be automatically determined by MATLAB or mlint executable. 71 | Use `semantic-matlab-system-paths-include' to let semantic know 72 | which system directories you would like to include when doing 73 | completions.") 74 | 75 | (defun semantic-matlab-root-directory () 76 | "Calculate the current MATLAB root directory." 77 | (if (matlab-shell-active-p) 78 | (matlab-shell-matlabroot) 79 | semantic-matlab-root-directory)) 80 | 81 | ;; The version of this variable in MATLAB.el is not condusive to extracting 82 | ;; the information we need. 83 | (defvar semantic-matlab-match-function-re 84 | "\\(^\\s-*function\\b[ \t\n.]*\\)\\(\\[[^]]+\\]\\s-*=\\|\\w+\\s-*=\\|\\)\\s-*\\(\\(\\sw\\|\\s_\\)+\\)\\>" 85 | "Expression to match a function start line.") 86 | 87 | ;; This function may someday be a part of matlab.el. 88 | ;; It does the raw scan and split for function tags. 89 | (defun semantic-matlab-function-tags (&optional buffer) 90 | "Find all MATLAB function tags in BUFFER. 91 | Return argument is: 92 | (START END RETURNVARS NAME ARGUMENTS DOCSTRING). 93 | Note that builtin functions from MATLAB will always return 94 | START=END=0 and no arguments or return values." 95 | (save-excursion 96 | (if buffer (set-buffer buffer)) 97 | (let ((re semantic-matlab-match-function-re) 98 | start ret fn arg end doc 99 | (taglist nil) 100 | ) 101 | (goto-char (point-min)) 102 | (if (and (string-match (format "^%s" (semantic-matlab-root-directory)) 103 | (buffer-file-name)) 104 | (looking-at "%\\([A-Z0-9_]+\\)\\s-+\\(.*\\)\\s-*$")) 105 | ;; This is a builtin function, ie there's no function line. 106 | ;; Hence we must use function name from the doc string. 107 | ;; FIXME 108 | ;; How can we get function arguments/return vals for builtin func's? 109 | (setq taglist 110 | (cons (list 0 0 nil (downcase (match-string-no-properties 1)) 111 | nil (match-string-no-properties 2) t 112 | ) 113 | taglist)) 114 | ;; this is a either not builtin or a user function 115 | (while (re-search-forward re nil t) 116 | (setq start (match-beginning 0) 117 | ret (buffer-substring-no-properties 118 | (match-beginning 2) (match-end 2)) 119 | fn (buffer-substring-no-properties 120 | (match-beginning 3) (match-end 3)) 121 | arg (buffer-substring-no-properties 122 | (match-end 3) (save-excursion 123 | (matlab-end-of-command) 124 | (point))) 125 | doc (save-excursion 126 | (forward-line) 127 | (beginning-of-line) 128 | ;; snarf doc string 129 | (cond 130 | ;; Mathworks standard 131 | ((looking-at "%[A-Z0-9_]+\\s-+\\(.*\\)\\s-*$") 132 | (match-string-no-properties 1)) 133 | ;; lookfor string 134 | ((looking-at "%\\s-+\\(.*\\)\\s-*$") 135 | (match-string-no-properties 1)) 136 | ;; otherwise simply snarf first line of 137 | ;; comments under function declaration 138 | (t 139 | (re-search-forward "[^[:blank:][:cntrl:]]" nil t) 140 | (backward-char) 141 | (if (looking-at "%\\s-+\\(.*\\)") 142 | (match-string-no-properties 1) 143 | nil)))) 144 | end (save-excursion 145 | (goto-char start) 146 | (if matlab-functions-have-end 147 | (condition-case nil 148 | ;; If we get a failure, we should at least 149 | ;; return whatever we got so far. 150 | (matlab-forward-sexp) 151 | (error (point-max))) 152 | (matlab-end-of-defun)) 153 | (point))) 154 | (setq taglist 155 | (cons (list start end 156 | (split-string ret "[][,=. \t\n]+" t) 157 | fn 158 | (split-string arg "[(), \n\t.]+" t) 159 | doc 160 | nil 161 | ) 162 | taglist)))) 163 | (nreverse taglist)))) 164 | 165 | (defun semantic-matlab-parse-oldstyle-class (tags &optional buffer) 166 | "Check if BUFFER with current TAGS is the constructor of a class. 167 | If this is the case, retrieve attributes from the buffer and scan 168 | the whole directory for methods. The function returns a single tag 169 | describing the class. This means that in semantic-matlab, the 170 | old-style MATLAB classes are linked to the constructor file." 171 | (let* ((name (buffer-file-name buffer)) 172 | class method methods retval attributes) 173 | (when (string-match ".*/@\\(.*?\\)/\\(.*?\\)\\.m" name) 174 | ;; this buffer is part of a class - check 175 | (setq class (match-string 1 name)) 176 | (setq method (match-string 2 name)) 177 | (when (string= class method) ; is this the constructor? 178 | ;; get attributes of the class 179 | ;; TODO - we blindly assume the constructor is correctly defined 180 | (setq retval (semantic-tag-get-attribute (car tags) :return)) 181 | (goto-char (point-min)) 182 | ;; search for attributes 183 | (while (re-search-forward 184 | (concat "^\\s-*" (car retval) 185 | "\\.\\([A-Za-z0-9_]+\\)\\s-*=\\s-*\\(.+\\);") 186 | nil t) 187 | (push (list (match-string-no-properties 1) ; name 188 | (match-string-no-properties 2)) ; default value 189 | attributes)) 190 | ;; now scan the methods 191 | (dolist (cur (delete class 192 | (nthcdr 2 193 | (assoc class semanticdb-matlab-user-class-cache)))) 194 | (push 195 | (semantic-tag-put-attribute 196 | (car (semanticdb-file-stream 197 | (concat 198 | (file-name-directory name) 199 | cur ".m"))) 200 | :typemodifiers '("public")) 201 | methods)) 202 | ;; generate tag 203 | (semantic-tag-new-type 204 | class 205 | "class" 206 | (append 207 | (mapcar (lambda (cur) 208 | (semantic-tag-new-variable 209 | (car cur) nil (cdr cur) 210 | :typemodifiers '("public"))) 211 | attributes) 212 | methods) 213 | nil 214 | :typemodifiers '("public")))))) 215 | 216 | (defun semantic-matlab-find-oldstyle-classes (files) 217 | "Scan FILES for old-style Matlab class system. 218 | Returns an alist with elements (CLASSNAME LOCATION METHODS)." 219 | (let (classes temp tags) 220 | (dolist (cur files) 221 | ;; scan file path for @-directory 222 | (when (string-match "\\(.*\\)/@\\(.*?\\)/\\(.*?\\)\\.m" cur) 223 | (if (setq temp 224 | (assoc (match-string 2 cur) classes)) 225 | (nconc temp `(,(match-string 3 cur))) 226 | (push `( ,(match-string 2 cur) ,(match-string 1 cur) 227 | ,(match-string 3 cur)) classes)))) 228 | classes)) 229 | 230 | ;;; BEGIN PARSER 231 | ;; 232 | (defun semantic-matlab-parse-region (&rest ignore) 233 | "Parse the current MATLAB buffer for function definitions. 234 | IGNORE any arguments which specify a subregion to parse. 235 | Each tag returned is a semantic FUNCTION tag. See 236 | `semantic-tag-new-function'." 237 | (semanticdb-matlab-cache-files) 238 | (let ((raw (condition-case nil 239 | ;; Errors from here ought not to be propagated. 240 | (semantic-matlab-parse-functions) 241 | (error nil))) 242 | tags ctags) 243 | (setq tags (mapcar 'semantic-matlab-expand-tag raw)) 244 | ;; check if this is a class constructor 245 | (setq ctags (list (semantic-matlab-parse-oldstyle-class tags))) 246 | (if (car ctags) 247 | ctags 248 | tags))) 249 | 250 | (defun semantic-matlab-parse-changes () 251 | "Parse all changes for the current MATLAB buffer." 252 | ;; NOTE: For now, just schedule a full reparse. 253 | ;; To be implemented later. 254 | (semantic-parse-tree-set-needs-rebuild)) 255 | 256 | (defun semantic-matlab-expand-tag (tag) 257 | "Expand the MATLAB function tag TAG." 258 | (let ((chil (semantic-tag-components-with-overlays tag))) 259 | (if chil 260 | (semantic-tag-put-attribute 261 | tag :members (mapcar 'semantic-matlab-expand-tag chil))) 262 | (car (semantic--tag-expand tag)))) 263 | 264 | (defun semantic-matlab-parse-functions () 265 | "Parse all functions from the current MATLAB buffer." 266 | (car 267 | (semantic-matlab-sort-raw-tags (semantic-matlab-function-tags) 268 | (point-max)) 269 | )) 270 | 271 | (defun semantic-matlab-sort-raw-tags (tag-list &optional end) 272 | "Return a split list of tags from TAG-LIST before END. 273 | Return list is: 274 | (TAGS-BEFORE-END REMAINING-TAGS)" 275 | (let ((newlist nil) 276 | (rest tag-list)) 277 | ;; Loop until there are no more tags, or no tags before END. 278 | (while (and tag-list (> end (car (car tag-list)))) 279 | (let* ((tag (car tag-list)) 280 | (start (car tag)) 281 | (end (nth 1 tag)) 282 | (ret (nth 2 tag)) 283 | (name (nth 3 tag)) 284 | (args (nth 4 tag)) 285 | (doc (nth 5 tag)) 286 | (builtin (nth 6 tag)) 287 | (parts (semantic-matlab-sort-raw-tags (cdr tag-list) end)) 288 | (chil (car parts))) 289 | (setq rest (car (cdr parts))) 290 | (setq newlist 291 | (cons (append 292 | (semantic-tag-new-function name nil args 293 | :return ret 294 | :subfunctions chil 295 | :documentation doc 296 | :builtin builtin) 297 | (list start end)) 298 | newlist)) 299 | (setq tag-list rest))) 300 | (list (nreverse newlist) tag-list))) 301 | 302 | ;; The following function tries to parse MATLAB variable 303 | ;; assignments. There are only three categories of types: doubles, 304 | ;; structs, and classes. It returns a list with elements 305 | ;; (NAME TYPE ATTRIBUTES), for example: 306 | ;; ("astruct" "struct" "field1" "field2" "field3") 307 | ;; ("aclass" "class" "exampleclass") 308 | ;; ("anumber" "double" "1356") 309 | ;; Of course we can't parse things we don't know, e.g. 310 | ;; if (a==5) variable=aclass; else variable=anotherclass; 311 | ;; In these cases, the latter assignment counts. 312 | ;; Also, we don't know return types of functions (yet...) - the parser 313 | ;; will always think it's "double". You can override the 314 | ;; parser with a special comment, like: %type% avariable = aclass 315 | 316 | ;; One day we might use a grammar for this...? 317 | 318 | (defconst semantic-matlab-type-hint-string "%type%" 319 | "Comment string which prefixes a type hint for the parser.") 320 | 321 | (defun semantic-matlab-parse-assignments () 322 | "Parse assignments in current buffer. 323 | This function starts at current point and goes backwards, until 324 | it reaches a function declaration or the beginning of the buffer. 325 | It returns a list of variable assignments (NAME TYPE ATTRIBUTES), 326 | where NAME is unique." 327 | (let ((limit (or (save-excursion 328 | (if (re-search-backward semantic-matlab-match-function-re nil t) 329 | (progn 330 | (forward-line 1) 331 | (point)) 332 | nil)) 333 | (point-min))) 334 | vars) 335 | ;; don't parse current line 336 | (beginning-of-line) 337 | (while (re-search-backward (concat "^\\(" (regexp-quote semantic-matlab-type-hint-string) 338 | "\\)?\\([^%]*[^=><~]\\)=\\([^=].*\\)$") limit t) 339 | (let ((left (match-string-no-properties 2)) 340 | (right (match-string-no-properties 3)) 341 | temp) 342 | ;; first we have to deal with elipsis... 343 | (save-excursion 344 | (while (string-match 345 | (concat "\\(.*\\)" 346 | (regexp-quote matlab-elipsis-string) "\\s-*$") 347 | right) 348 | (forward-line 1) 349 | (setq right 350 | (concat 351 | (match-string 1 right) 352 | (progn (looking-at "^.*$") 353 | (match-string-no-properties 0)))))) 354 | (save-excursion 355 | (while (and (not (bobp)) 356 | (progn 357 | (forward-line -1) 358 | (looking-at 359 | (concat "\\(.*\\)" 360 | (regexp-quote matlab-elipsis-string) "\\s-*$")))) 361 | (setq left 362 | (concat (match-string-no-properties 1) left)))) 363 | ;; remove bracket expressions and beginning/trailing whitespaces on left-hand side 364 | (while (or (string-match "\\((.*)\\|{.*}\\)" left) 365 | (string-match "^\\(\\s-+\\)" left) 366 | (string-match "\\(\\s-+\\)$" left)) 367 | (setq left (replace-match "" t t left))) 368 | ;; deal with right-hand side 369 | (cond 370 | ;; special case: a = set(class,attribute,value) 371 | ((string-match "\\s-*set(\\s-*\\([A-Za-z_0-9 ]+\\)\\s-*," right) 372 | (setq right (match-string 1 right))) 373 | ;; method call which returns same class: class=method(class [,args]) 374 | ((and (string-match "\\s-*[A-Za-z_0-9 ]+\\s-*(\\s-*\\([A-Za-z_0-9 ]+\\)\\s-*\\(,\\|)\\)" right) 375 | (string= left (match-string 1 right))) 376 | (setq right (match-string 1 right))) 377 | ;; otherwise reduce right-hand side to first symbol 378 | (t 379 | (string-match "[[({ ]*\\([A-Za-z_0-9]*\\)" right) 380 | (setq right (match-string 1 right)))) 381 | (cond 382 | ;; multiple assignment, e.g. [a,b]=size(A); 383 | ((string-match "\\[\\(.*\\)\\]" left) 384 | (dolist (cur (split-string (match-string 1 left) ",")) 385 | (string-match "\\s-*\\([A-Za-z_0-9]+\\)\\s-*" cur) 386 | (setq cur (match-string 1 cur)) 387 | (unless (assoc cur vars) 388 | ;; since we don't know any return types, we just say it's double 389 | (push (list cur "double" "") vars)))) 390 | ;; (nested) structure 391 | ((string-match "\\([A-Za-z_0-9.]+\\)\\.\\([A-Za-z_0-9]+\\)" left) 392 | (while (string-match "\\([A-Za-z_0-9.]+\\)\\.\\([A-Za-z_0-9]+\\)" left) 393 | (let ((name (match-string 1 left)) 394 | (field (match-string 2 left))) 395 | (if (setq temp (assoc name vars)) 396 | (unless (member field temp) 397 | (nconc temp (list field))) 398 | (push (list name "struct" field) 399 | vars)) 400 | (setq left name)))) 401 | ;; class 402 | ((assoc right semanticdb-matlab-user-class-cache) 403 | (string-match "\\([A-Za-z_0-9]+\\)\\s-*$" left) 404 | (setq left (match-string 1 left)) 405 | (if (and (setq temp (assoc left vars)) 406 | (string= (nth 1 temp) "struct")) 407 | ;; we first thought it's a structure, but it's probably a 408 | ;; new-style class 409 | (setcdr temp `("class" ,right)) 410 | (unless temp 411 | (push `(,left "class" ,right) vars)))) 412 | (t 413 | ;; default is double 414 | (string-match "\\([A-Za-z_0-9]+\\)\\s-*$" left) 415 | (setq left (match-string 1 left)) 416 | (unless (or (assoc left vars) 417 | (string= left right)) ; self assignment 418 | (push `(,left "double" ,right) vars))) 419 | ))) 420 | vars)) 421 | 422 | 423 | 424 | (define-mode-local-override semantic-get-local-variables 425 | matlab-mode (&optional point) 426 | "Return a list of local variables for POINT." 427 | (semanticdb-matlab-cache-files) 428 | (save-excursion 429 | (let ((vars (semantic-matlab-parse-assignments)) 430 | knowntypes tags) 431 | (dolist (cur vars) 432 | ;; check right-hand side for known types which might be 433 | ;; assigned this variable 434 | (if (string= (nth 1 cur) "double") 435 | (when (member (nth 2 cur) knowntypes) 436 | (setcdr cur (cdr (assoc (nth 2 cur) vars)))) 437 | (push (nth 0 cur) knowntypes)) 438 | ;; generate the tag 439 | (push 440 | (semantic-tag-new-variable 441 | (car cur) 442 | (cond 443 | ;; structures 444 | ((string= (cadr cur) "struct") 445 | (semantic-tag-new-type 446 | ;; this is just a placeholder 447 | (concat (car cur) "_struct") 448 | "struct" 449 | (mapcar 450 | (lambda (x) 451 | (semantic-tag-new-variable 452 | x 453 | nil nil :typemodifiers '("public") )) 454 | (nthcdr 2 cur)) 455 | nil)) 456 | ;; classes 457 | ((string= (cadr cur) "class") 458 | ;; include tags from class constructor 459 | ;; (contains whole class, including methods) 460 | (car (semanticdb-file-stream 461 | (concat 462 | (nth 1 (assoc (nth 2 cur) semanticdb-matlab-user-class-cache)) 463 | "/@" (nth 2 cur) "/" (nth 2 cur) ".m")))) 464 | (t 465 | nil))) 466 | tags)) 467 | tags))) 468 | 469 | 470 | (define-mode-local-override semantic-tag-components-with-overlays 471 | matlab-mode (tag) 472 | "Return the list of subfunctions in TAG." 473 | (semantic-tag-get-attribute tag :subfunctions)) 474 | 475 | (define-mode-local-override semantic-format-tag-prototype matlab-mode 476 | (tag &optional parent color) 477 | "Return a prototype string describing tag. 478 | For MATLAB, we have to mark builtin functions, since we currently 479 | cannot derive an argument list for them." 480 | (let ((class (semantic-tag-class tag)) 481 | (name (semantic-format-tag-name tag parent color)) 482 | str) 483 | (if (eq class 'function) 484 | (let* ((args (semantic-tag-function-arguments tag)) 485 | (argstr (semantic--format-tag-arguments args 486 | #'identity 487 | color)) 488 | (builtin (semantic-tag-get-attribute tag :builtin)) 489 | (doc (semantic-tag-docstring tag))) 490 | (if builtin 491 | (if color 492 | (setq builtin (semantic--format-colorize-text " [builtin] " 'keyword) 493 | argstr (semantic--format-colorize-text " arguments unavailable" 'label)) 494 | (setq builtin " [builtin] " 495 | argstr " arguments unavailable")) 496 | (setq builtin "")) 497 | (concat name builtin "(" (if args " " "") 498 | argstr 499 | " )")) 500 | (semantic-format-tag-prototype-default tag parent color)))) 501 | 502 | (defun semantic-idle-summary-format-matlab-mode (tag &optional parent color) 503 | "Describe TAG and display corresponding MATLAB 'lookfor' doc-string." 504 | (let* ((proto (semantic-format-tag-prototype-matlab-mode tag nil color)) 505 | (doc (semantic-tag-docstring tag))) 506 | (concat proto " (" doc ")"))) 507 | 508 | (defcustom-mode-local-semantic-dependency-system-include-path 509 | matlab-mode semantic-matlab-dependency-system-include-path 510 | (if semantic-matlab-root-directory 511 | (mapcar (lambda (cur) 512 | (concat (file-name-as-directory semantic-matlab-root-directory) 513 | cur)) 514 | semantic-matlab-system-paths-include) 515 | nil) 516 | "The system include paths from MATLAB.") 517 | 518 | (defvar-mode-local matlab-mode semantic-idle-summary-function 519 | 'semantic-idle-summary-format-matlab-mode 520 | "Function to use when displaying tag information during idle time.") 521 | 522 | (defvar semantic-matlab-display-docstring t 523 | "Flag if function documentation should be displayed after completion.") 524 | 525 | (define-mode-local-override semantic-ia-insert-tag 526 | matlab-mode (tag) 527 | "Insert TAG into the current buffer based on completion." 528 | (insert (semantic-tag-name tag)) 529 | (let ((name (semantic-tag-name tag)) 530 | (tt (semantic-tag-class tag)) 531 | (args (semantic-tag-function-arguments tag)) 532 | (doc (semantic-tag-docstring tag))) 533 | (when (and (eq tt 'function) 534 | args 535 | (not (looking-at "\\s-*("))) 536 | (insert "(")) 537 | ;; delete trailing whitespaces when completing class methods 538 | (when (looking-at "\\(\\s-+\\)(") 539 | (delete-char (length (match-string 1)))) 540 | (when semantic-matlab-display-docstring 541 | (fame-message-nolog 542 | (semantic-idle-summary-format-matlab-mode tag nil t))))) 543 | 544 | (define-mode-local-override semantic-ctxt-current-symbol 545 | matlab-mode (&optional point) 546 | "Return the current symbol the cursor is on at point in a list. 547 | This will include a list of type/field names when applicable." 548 | (let* ((case-fold-search semantic-case-fold) 549 | sym) 550 | (with-syntax-table semantic-lex-syntax-table 551 | (save-excursion 552 | (when point (goto-char point)) 553 | ;; go to beginning of symbol 554 | (skip-syntax-backward "w_") 555 | (setq sym (if (looking-at "[a-zA-Z_0-9]+") 556 | (match-string-no-properties 0) 557 | nil)) 558 | (if sym 559 | (cond 560 | ;; method call: var = method(class,args) 561 | ((progn 562 | (and (looking-back "[^=><~]=\\s-*") 563 | (looking-at "[a-zA-Z_0-9]*\\s-*(\\([a-zA-Z_0-9]+\\),?"))) 564 | (list (match-string-no-properties 1) sym)) 565 | ;; class properties: var = get(class,'attribute') 566 | ((looking-back "\\(get\\|set\\)(\\s-*\\([a-zA-Z_0-9]+\\),'") 567 | (list (match-string-no-properties 2) sym)) 568 | ;; (nested) structures or new-style classes 569 | ((looking-back "[^A-Za-z_0-9.]\\([A-Za-z_0-9.]+\\)\\.") 570 | (list (match-string-no-properties 1) sym)) 571 | (t 572 | (list sym))) 573 | nil))))) 574 | 575 | (define-mode-local-override semantic-ctxt-current-symbol-and-bounds 576 | matlab-mode (&optional point) 577 | "Return the current symbol and bounds the cursor is on at POINT. 578 | Uses `semantic-ctxt-current-symbol' to calculate the symbol. 579 | Return (PREFIX ENDSYM BOUNDS)." 580 | (let ((sym (semantic-ctxt-current-symbol-matlab-mode point)) 581 | bounds endsym) 582 | (save-excursion 583 | (when point (goto-char point)) 584 | (when sym 585 | ;; go to beginning of symbol 586 | (skip-syntax-backward "w_") 587 | (setq endsym (progn (looking-at "[a-zA-Z_0-9]+") 588 | (match-string-no-properties 0))) 589 | (setq bounds (cons 590 | (match-beginning 0) 591 | (match-end 0))) 592 | (list sym endsym bounds))))) 593 | 594 | 595 | ;;;###autoload 596 | (defun semantic-default-matlab-setup () 597 | "Set up a buffer for parsing of MATLAB files." 598 | ;; This will use our parser. 599 | (semantic-install-function-overrides 600 | '((parse-region . semantic-matlab-parse-region) 601 | (parse-changes . semantic-matlab-parse-changes))) 602 | (setq semantic-parser-name "MATLAB" 603 | ;; Setup a dummy parser table to enable parsing! 604 | semantic--parse-table t 605 | imenu-create-index-function 'semantic-create-imenu-index 606 | ;; semantic-command-separation-character "." 607 | semantic-type-relation-separator-character '(".") 608 | semantic-symbol->name-assoc-list '((function . "Function") 609 | ) 610 | semantic-imenu-expandable-tag-classes '(function) 611 | semantic-imenu-bucketize-file nil 612 | semantic-imenu-bucketize-type-members nil 613 | senator-step-at-start-end-tag-classes '(function) 614 | semantic-stickyfunc-sticky-classes '(function) 615 | ) 616 | ) 617 | 618 | (provide 'semantic-matlab) 619 | 620 | ;;; semantic-matlab.el ends here 621 | -------------------------------------------------------------------------------- /semanticdb-matlab.el: -------------------------------------------------------------------------------- 1 | ;;; semanticdb-matlab.el --- Semantic database extensions for MATLAB 2 | 3 | ;;; Copyright (C) 2008, 2012, 2013 David Engster 4 | 5 | ;; Author: David Engster 6 | ;; based heavily on semanticdb-skel.el (C) Eric Ludlam 7 | 8 | ;; This file is not part of GNU Emacs. 9 | 10 | ;; This is free software; you can redistribute it and/or modify 11 | ;; it under the terms of the GNU General Public License as published by 12 | ;; the Free Software Foundation; either version 2, or (at your option) 13 | ;; any later version. 14 | 15 | ;; This software is distributed in the hope that it will be useful, 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | ;; GNU General Public License for more details. 19 | 20 | ;; You should have received a copy of the GNU General Public License 21 | ;; along with GNU Emacs; see the file COPYING. If not, write to the 22 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 23 | ;; Boston, MA 02110-1301, USA. 24 | 25 | ;; For generic function searching. 26 | (require 'eieio) 27 | (require 'eieio-opt) 28 | 29 | ;; eval-and-compile needed because of the condition-case. 30 | ;; Normally a require is eval'd during compile, so this is the same. 31 | (eval-and-compile 32 | (condition-case nil 33 | (require 'semanticdb) 34 | (error (require 'semantic/db)))) 35 | 36 | ;;; Code: 37 | 38 | ;; Put all directories which should be recursively scanned for your 39 | ;; personal MATLAB files here. 40 | 41 | (defvar semanticdb-matlab-include-paths 42 | (if (file-exists-p (expand-file-name "~/matlab")) 43 | (list (expand-file-name "~/matlab") ;; Default location for extra code. 44 | ) 45 | ;; Else, no default path. 46 | nil) 47 | "Directories which should be scanned for m-files.") 48 | 49 | ;;; Classes: 50 | (defclass semanticdb-table-matlab (semanticdb-search-results-table) 51 | ((major-mode :initform matlab-mode) 52 | ) 53 | "A table for returning search results from MATLAB path.") 54 | 55 | (defclass semanticdb-project-database-matlab 56 | (semanticdb-project-database 57 | ;; Use SINGLETON if there should be only one copy of this database. 58 | ;; Do not use this if you need a different copy for different projects. 59 | ;; eieio-singleton 60 | ) 61 | ((new-table-class :initform semanticdb-table-matlab 62 | :type class 63 | :documentation 64 | "New tables created for this database are of this class.") 65 | ) 66 | "Database representing MATLAB path.") 67 | 68 | ;; Create the database, and add it to searchable databases for matlab mode. 69 | (defvar-mode-local matlab-mode semanticdb-project-system-databases 70 | (list 71 | (semanticdb-project-database-matlab "Matlab")) 72 | "Search MATLAB path for symbols.") 73 | 74 | ;; NOTE: Be sure to modify this to the best advantage of your 75 | ;; language. 76 | (defvar-mode-local matlab-mode semanticdb-find-default-throttle 77 | '(project omniscience) 78 | "Search project files, then search this omniscience database. 79 | It is not necessary to to system or recursive searching because of 80 | the omniscience database.") 81 | 82 | ;;; Filename based methods 83 | ;; 84 | (defmethod semanticdb-get-database-tables ((obj semanticdb-project-database-matlab)) 85 | "For a MATLAB database, there are no explicit tables. 86 | Create one of our special tables that can act as an intermediary." 87 | ;; NOTE: This method overrides an accessor for the `tables' slot in 88 | ;; a database. You can either construct your own (like tmp here 89 | ;; or you can manage any number of tables. 90 | 91 | ;; We need to return something since there is always the "master table" 92 | ;; The table can then answer file name type questions. 93 | (when (not (slot-boundp obj 'tables)) 94 | (let ((newtable (semanticdb-table-matlab "MATLAB system table"))) 95 | (oset obj tables (list newtable)) 96 | (oset newtable parent-db obj) 97 | (oset newtable tags nil) 98 | )) 99 | (call-next-method)) 100 | 101 | (defmethod semanticdb-file-table ((obj semanticdb-project-database-matlab) filename) 102 | "From OBJ, return FILENAME's associated table object." 103 | ;; NOTE: See not for `semanticdb-get-database-tables'. 104 | (car (semanticdb-get-database-tables obj)) 105 | ) 106 | 107 | (defmethod semanticdb-get-tags ((table semanticdb-table-matlab )) 108 | "Return the list of tags belonging to TABLE." 109 | ;; NOTE: Omniscient databases probably don't want to keep large tabes 110 | ;; lolly-gagging about. Keep internal Emacs tables empty and 111 | ;; refer to alternate databases when you need something. 112 | nil) 113 | 114 | (defmethod semanticdb-equivalent-mode ((table semanticdb-table-matlab) &optional buffer) 115 | "Return non-nil if TABLE's mode is equivalent to BUFFER. 116 | Equivalent modes are specified by by `semantic-equivalent-major-modes' 117 | local variable." 118 | (save-excursion 119 | (set-buffer buffer) 120 | (eq (or mode-local-active-mode major-mode) 'matlab-mode))) 121 | 122 | (defmethod semanticdb-full-filename ((obj semanticdb-table-matlab)) 123 | "Fetch the full filename that OBJ refers to. 124 | This function is currently a stub." 125 | ;; FIXME 126 | ;; return filename for object - what should we do with builtin functions? 127 | nil) 128 | 129 | 130 | ;;; Usage 131 | ;; 132 | ;; Unlike other tables, an omniscent database does not need to 133 | ;; be associated with a path. Use this routine to always add ourselves 134 | ;; to a search list. 135 | (define-mode-local-override semanticdb-find-translate-path matlab-mode 136 | (path brutish) 137 | "Return a list of semanticdb tables asociated with PATH. 138 | If brutish, do the default action. 139 | If not brutish, do the default action, and append the system 140 | database (if available.)" 141 | (let ((default 142 | ;; When we recurse, disable searching of system databases 143 | ;; so that our MATLAB database only shows up once when 144 | ;; we append it in this iteration. 145 | (let ((semanticdb-search-system-databases nil) 146 | ) 147 | (semanticdb-find-translate-path-default path brutish)))) 148 | ;; Don't add anything if BRUTISH is on (it will be added in that fcn) 149 | ;; or if we aren't supposed to search the system. 150 | (if (or brutish (not semanticdb-search-system-databases)) 151 | default 152 | (let ((tables (apply #'append 153 | (mapcar 154 | (lambda (db) (semanticdb-get-database-tables db)) 155 | semanticdb-project-system-databases)))) 156 | (append default tables))))) 157 | 158 | ;;; Search Overrides 159 | ;; 160 | ;; NOTE WHEN IMPLEMENTING: Be sure to add doc-string updates explaining 161 | ;; how your new search routines are implemented. 162 | ;; 163 | 164 | 165 | (defvar semanticdb-matlab-system-files-cache '(nil) 166 | "Internal cache for system M files. 167 | This variable caches all M files in the directories listed in 168 | `semantic-matlab-system-paths-include' under MATLAB root 169 | directory. Users can reset this cache using 170 | `semanticdb-matlab-reset-files-cache'") 171 | 172 | (defvar semanticdb-matlab-user-files-cache '(nil) 173 | "Internal cache for user M files. 174 | This variable caches all M files in the directories listed in 175 | `semanticdb-matlab-include-paths'. Users can reset this cache 176 | using `semanticdb-matlab-reset-files-cache'.") 177 | 178 | (defvar semanticdb-matlab-user-class-cache nil 179 | "Internal cache for user classes.") 180 | 181 | (defun semanticdb-matlab-reset-files-cache () 182 | "Reset semanticdb-matlab file cache." 183 | (interactive) 184 | (setq semanticdb-matlab-user-files-cache '(nil)) 185 | (setq semanticdb-matlab-system-files-cache '(nil))) 186 | 187 | (defun semanticdb-matlab-possibly-add-buffer-to-cache () 188 | "Add current buffer file name to cache. 189 | This function will add the current buffer file name to 190 | `semanticdb-matlab-user-files-cache' if not already there. Meant 191 | to be called in local `after-save-hook'." 192 | (unless (and semanticdb-matlab-user-files-cache 193 | (member (buffer-file-name) 194 | (cdr semanticdb-matlab-user-files-cache))) 195 | (setcdr semanticdb-matlab-user-files-cache 196 | (append (cdr semanticdb-matlab-user-files-cache) 197 | (list (buffer-file-name)))))) 198 | 199 | ;; Make sure newly created MATLAB files get in the user-files-cache 200 | (add-hook 'matlab-mode-hook 201 | (lambda () 202 | ;; add buffer-local after-save-hook 203 | (add-hook 204 | 'after-save-hook 205 | 'semanticdb-matlab-possibly-add-buffer-to-cache t t))) 206 | 207 | ;; Helper functions 208 | 209 | (defun semanticdb-matlab-scan-directories 210 | (dirs &optional recursive exclude-classes exclude-private) 211 | "Get list of all m-files in DIRS. 212 | DIRS is a list of directories. If RECURSIVE, every subdirectory 213 | will be included in the search. If EXCLUDE-CLASSES, class 214 | directories (beginning with '@') will be skipped. If 215 | EXCLUDE-PRIVATE, 'private' directories will be skipped." 216 | (if dirs 217 | (let (files) 218 | (dolist (dir dirs) 219 | (let (subdirs) 220 | (dolist (cur (directory-files dir t "[^.]" t)) 221 | (if (file-directory-p cur) 222 | (when (and recursive 223 | (not (and exclude-classes 224 | (string-match ".*/@" cur))) 225 | (not (and exclude-private 226 | (string-match ".*/private$" cur)))) 227 | (push cur subdirs)) 228 | (when (string-match "\\.m$" cur) 229 | (push cur files)))) 230 | (when subdirs 231 | (setq files 232 | (append files 233 | (semanticdb-matlab-scan-directories 234 | subdirs recursive exclude-classes exclude-private)))))) 235 | files) 236 | nil)) 237 | 238 | (defun semanticdb-matlab-cache-files () 239 | "Cache user and system MATLAB files if necessary." 240 | ;; car of *-file-cache variables is used as flag 241 | (unless (car semanticdb-matlab-system-files-cache) 242 | (setq semanticdb-matlab-system-files-cache 243 | (cons t 244 | (semanticdb-matlab-scan-directories 245 | semantic-matlab-dependency-system-include-path t t t)))) 246 | (unless (car semanticdb-matlab-user-files-cache) 247 | (setq semanticdb-matlab-user-files-cache 248 | (cons t 249 | (semanticdb-matlab-scan-directories 250 | semanticdb-matlab-include-paths t nil nil))) 251 | ;; cache user defined old-style classes 252 | (setq semanticdb-matlab-user-class-cache 253 | (semantic-matlab-find-oldstyle-classes 254 | (cdr semanticdb-matlab-user-files-cache))))) 255 | 256 | (defun semanticdb-matlab-find-name (name &optional type) 257 | "Find NAME in matlab file names. 258 | If TYPE is 'regex, NAME is a regular expression. 259 | If TYPE is 'prefix, NAME is a prefix." 260 | (semanticdb-matlab-cache-files) 261 | (let ((files (append (cdr semanticdb-matlab-system-files-cache) 262 | (cdr semanticdb-matlab-user-files-cache))) 263 | regexp results) 264 | (cond 265 | ((eq type 'prefix) 266 | (setq regexp (format "^%s.*\\.m$" name))) 267 | ((eq type 'regex) 268 | (setq regexp (format "%s\\.m$" name))) 269 | (t 270 | (setq regexp (format "^%s\\.m" name)))) 271 | (dolist (cur files) 272 | (when (string-match regexp (file-name-nondirectory cur)) 273 | (push cur results))) 274 | results)) 275 | 276 | (define-mode-local-override semantic-ctxt-current-class-list 277 | matlab-mode (point) 278 | "Return a list of tag classes that are allowed at point. 279 | If point is nil, the current buffer location is used." 280 | (cond 281 | ((looking-at ".+=") 282 | '(variable type)) 283 | ((looking-back "\\(get\\|set\\)([a-zA-Z_0-9]*") 284 | '(variable type)) 285 | ((looking-back "\\(get\\|set\\)([a-zA-Z_0-9]+,'[a-zA-Z_0-9]*") 286 | '(variable)) 287 | ((looking-back "\\.[a-zA-Z_0-9]*") 288 | '(variable)) 289 | ((looking-at "\\s-*([a-zA-Z_0-9]+,") 290 | '(function)) 291 | (t 292 | '(function variable type)))) 293 | 294 | ;; Search functions 295 | 296 | (defmethod semanticdb-find-tags-by-name-method 297 | ((table semanticdb-table-matlab) name &optional tags) 298 | "Find all tags named NAME in TABLE. 299 | Return a list of tags." 300 | ;; If we have tags, go up. 301 | (if tags (call-next-method) 302 | (let (where) 303 | ;; If MATLAB shell is active, use it. 304 | (when (and (matlab-shell-active-p) 305 | (setq where (matlab-shell-which-fcn name))) 306 | (when (and (not (file-exists-p (car where))) 307 | ;; Sometimes MATLAB builtin functions lie. 308 | (string-match "@" (car where))) 309 | (setq where 310 | (list 311 | (concat 312 | (substring (car where) 0 (match-beginning 0)) 313 | name ".m"))))) 314 | (unless (car where) 315 | ;; Fall back to home-made database. 316 | (setq where 317 | (list (car (semanticdb-matlab-find-name name))))) 318 | (if (car where) 319 | (list (car (semanticdb-file-stream (car where)))) 320 | nil)))) 321 | 322 | (defmethod semanticdb-find-tags-by-name-regexp-method 323 | ((table semanticdb-table-matlab) regex &optional tags) 324 | "Find all tags with name matching REGEX in TABLE. 325 | Optional argument TAGS is a list of tags to search. 326 | Return a list of tags." 327 | (if tags (call-next-method) 328 | (let ((files (semanticdb-matlab-find-name regex 'regex))) 329 | (delq nil 330 | (mapcar '(lambda (x) 331 | (let ((matlab-vers-on-startup nil)) 332 | (car (semanticdb-file-stream x)))) 333 | files))))) 334 | 335 | (defmethod semanticdb-find-tags-for-completion-method 336 | ((table semanticdb-table-matlab) prefix &optional tags) 337 | "In TABLE, find all occurances of tags matching PREFIX. 338 | Optional argument TAGS is a list of tags to search. 339 | Returns a table of all matching tags." 340 | ;; If we have tags, go up. 341 | (if tags (call-next-method) 342 | ;; first, get completions from home-made database... 343 | (let ((compdb (semanticdb-matlab-find-name prefix 'prefix)) 344 | compshell) 345 | ;; ...and from MATLAB shell, if available 346 | (when (matlab-shell-active-p) 347 | (setq compshell 348 | (mapcar 349 | (lambda (x) 350 | (let ((where (matlab-shell-which-fcn (car x)))) 351 | ;; correct name for builtin functions 352 | (when (and (cdr where) 353 | (string-match 354 | "\\(.*\\)/@.*\\(/[A-Za-z_0-9]+\\.m\\)" 355 | (car where))) 356 | (setq where 357 | (list 358 | (concat (match-string 1 (car where)) 359 | (match-string 2 (car where)))))) 360 | (list (car where)))) 361 | (matlab-shell-completion-list prefix))) 362 | ;; combine results 363 | (mapc 364 | (lambda (x) 365 | (unless (member x compdb) 366 | (setq compdb (append compdb x)))) 367 | compshell)) 368 | ;; generate tags 369 | (delq nil 370 | (mapcar '(lambda (x) 371 | (let ((matlab-vers-on-startup nil)) 372 | (car (semanticdb-file-stream x)))) 373 | compdb))))) 374 | 375 | (provide 'semanticdb-matlab) 376 | 377 | ;;; semanticdb-matlab.el ends here 378 | -------------------------------------------------------------------------------- /srecode-matlab.el: -------------------------------------------------------------------------------- 1 | ;;; srecode-matlab.el --- Extra SRecode support for MATLAB 2 | ;; 3 | ;; Copyright (C) 2014 Eric Ludlam 4 | ;; 5 | ;; Author: Eric Ludlam 6 | ;; X-RCS: $Id$ 7 | ;; 8 | ;; This program is free software; you can redistribute it and/or 9 | ;; modify it under the terms of the GNU General Public License as 10 | ;; published by the Free Software Foundation, either version 3 of the 11 | ;; License, or (at your option) any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, but 14 | ;; WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | ;; General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with this program. If not, see http://www.gnu.org/licenses/. 20 | 21 | ;;; Commentary: 22 | ;; 23 | ;; Support some extra dictionary entries for MATLAB code. 24 | 25 | (require 'srecode) 26 | (require 'srecode/dictionary) 27 | (require 'srecode/semantic) 28 | (require 'matlab) 29 | 30 | ;;; Code: 31 | 32 | ;;; :matlab ARGUMENT HANDLER 33 | ;; 34 | ;; When a :matlab argument is required, fill the dictionary info 35 | ;; with this MATLAB specific stuff. 36 | ;; 37 | ;; Error if not in MATLAB mode. 38 | 39 | ;;;###autoload 40 | (defun srecode-semantic-handle-:matlab (dict) 41 | "Add macros into the dictionary DICT based on the current MATLAB buffer. 42 | Adds the following: 43 | FILE_SYMBOL - The file name as a symbol. 44 | FILE_DOC_SYMBOL - The file name as a symbol for doc strings. 45 | PACKAGE - The package this file is in, or empty if none. 46 | FILE_CLASS - Show section if filename should be a class. 47 | FILE_FUNCTION - Show setion if filename is a function. 48 | 49 | On class prediction - when filling in an empty file, if the filename and directory it is in 50 | match, for example @foo/foo.m then foo should be a classdef." 51 | (when (not (eq major-mode 'matlab-mode)) 52 | (error "Wrong mode for :matlab argument")) 53 | (let* ((fsym (file-name-sans-extension (file-name-nondirectory (buffer-file-name)))) 54 | (dir (directory-file-name (file-name-directory (buffer-file-name)))) 55 | (dsym (file-name-nondirectory dir))) 56 | ;; Convert the file name to a symbol. 57 | (srecode-dictionary-set-value dict "FILE_SYMBOL" fsym) 58 | (srecode-dictionary-set-value dict "FILE_DOC_SYMBOL" (upcase fsym)) 59 | ;; Check that dsym and fsym are the same 60 | (if (string= dsym (concat "@" fsym)) 61 | (srecode-dictionary-show-section dict "FILE_CLASS") 62 | (srecode-dictionary-show-section dict "FILE_FUNCTION")) 63 | ;; Now look at the stack of directories to see what the package name 64 | ;; might be. 65 | (let ((package "") 66 | (next (file-name-nondirectory dir))) 67 | (setq dir (file-name-directory dir)) 68 | ;; Keep scanning for packages while there is a + in the path. 69 | (while (and (> (length dir) 0) (string-match "/\\+\\w" dir)) 70 | (let ((first (aref next 0)) 71 | (rest (substring next 1))) 72 | (if (= first ?+) 73 | (setq package (concat rest "." package)) 74 | (setq dir "")) 75 | ;; Setup for next iteration. 76 | (setq dir (directory-file-name (directory-file-name dir))) 77 | (setq next (file-name-nondirectory dir)) 78 | )) 79 | (srecode-dictionary-set-value dict "PACKAGE" package) 80 | ))) 81 | 82 | (provide 'srecode-matlab) 83 | 84 | ;;; srecode-matlab.el ends here 85 | -------------------------------------------------------------------------------- /templates/Makefile: -------------------------------------------------------------------------------- 1 | # Automatically Generated Makefile by EDE. 2 | # For use with: make 3 | # Relative File Name: templates/Makefile 4 | # 5 | # DO NOT MODIFY THIS FILE OR YOUR CHANGES MAY BE LOST. 6 | # EDE is the Emacs Development Environment. 7 | # http://cedet.sourceforge.net/ede.shtml 8 | # 9 | 10 | top=../ 11 | ede_FILES=Project.ede Makefile 12 | 13 | templates_MISC=srecode-matlab.srt 14 | VERSION=3.3.2 15 | DISTDIR=$(top)matlab-emacs-$(VERSION)/templates 16 | 17 | 18 | 19 | all: templates 20 | 21 | templates: 22 | @ 23 | 24 | tags: 25 | 26 | .PHONY: dist 27 | 28 | dist: 29 | mkdir $(DISTDIR) 30 | cp $(templates_MISC) $(ede_FILES) $(DISTDIR) 31 | 32 | Makefile: Project.ede 33 | @echo Makefile is out of date! It needs to be regenerated by EDE. 34 | @echo If you have not modified Project.ede, you can use 'touch' to update the Makefile time stamp. 35 | @false 36 | 37 | 38 | 39 | # End of Makefile 40 | -------------------------------------------------------------------------------- /templates/Project.ede: -------------------------------------------------------------------------------- 1 | ;; Object Templates 2 | ;; EDE project file. 3 | (ede-proj-project "Templates" 4 | :name "Templates" 5 | :file "Project.ede" 6 | :targets (list 7 | (ede-proj-target-makefile-miscelaneous "templates" 8 | :name "templates" 9 | :path "" 10 | :source '("srecode-matlab.srt") 11 | ) 12 | ) 13 | ) 14 | -------------------------------------------------------------------------------- /templates/srecode-matlab.srt: -------------------------------------------------------------------------------- 1 | ;; srecode-matlab.srt --- SREcode Templates for MATLAB. 2 | 3 | ;; Copyright (C) 2008, 2014 Eric Ludlam 4 | 5 | ;; Author: Eric Ludlam 6 | ;; X-RCS: $Id$ 7 | 8 | ;; This program is free software; you can redistribute it and/or 9 | ;; modify it under the terms of the GNU General Public License as 10 | ;; published by the Free Software Foundation; either version 2, or (at 11 | ;; your option) any later version. 12 | 13 | ;; This program is distributed in the hope that it will be useful, but 14 | ;; WITHOUT ANY WARRANTY; without even the implied warranty of 15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | ;; General Public License for more details. 17 | 18 | ;; You should have received a copy of the GNU General Public License 19 | ;; along with this program; see the file COPYING. If not, write to 20 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 | ;; Boston, MA 02110-1301, USA. 22 | 23 | 24 | set mode "matlab-mode" 25 | set escape_start "{{" 26 | set escape_end "}}" 27 | 28 | context file 29 | 30 | set comment_start "%" 31 | set comment_prefix "%" 32 | set comment_end "" 33 | 34 | ;; @todo - add argument support. 35 | ;; choose template based on script/function or class in current dir. 36 | template empty :matlab :file :user :time 37 | "Fill out an empty file." 38 | ---- 39 | {{#FILE_FUNCTION}}function {{FILE_SYMBOL}} 40 | {{comment_prefix}} {{FILE_DOC_SYMBOL}} - 41 | {{comment_prefix}} 42 | 43 | {{comment_prefix}} Copyright (C) {{YEAR}} {{?AUTHOR}} 44 | 45 | {{^}} 46 | 47 | end 48 | {{/FILE_FUNCTION}}{{#FILE_CLASS}}classdef {{FILE_SYMBOL}} 49 | {{comment_prefix}} Class {{FILE_DOC_SYMBOL}} 50 | {{comment_prefix}} 51 | 52 | {{comment_prefix}} Copyright (C) {{YEAR}} {{?AUTHOR}} 53 | 54 | properties 55 | 56 | end 57 | 58 | methods 59 | function h = {{FILE_SYMBOL}}({{^}}) 60 | % Constructor 61 | 62 | end 63 | end 64 | end 65 | 66 | {{/FILE_CLASS}} 67 | end 68 | ---- 69 | bind "e" 70 | 71 | 72 | context declaration 73 | 74 | 75 | prompt NAME "Name for declaration: " 76 | 77 | template classdef :time :user :time 78 | "Template to declare a class" 79 | ---- 80 | classdef {{?NAME}} 81 | % Class {{NAME:upcase}} 82 | % 83 | % Copyright (C) {{YEAR}} {{?AUTHOR}} 84 | 85 | properties 86 | 87 | end 88 | 89 | methods 90 | function h = {{NAME}}(varargin) 91 | {{^}} 92 | end 93 | end 94 | end 95 | ---- 96 | bind "c" 97 | 98 | template function :blank :indent 99 | "Template to declare a function." 100 | ---- 101 | function {{?NAME}} 102 | {{^}} 103 | end 104 | ---- 105 | bind "f" 106 | 107 | template variable :blank :indent 108 | "Template to declare a variable." 109 | ---- 110 | global {{?NAME}} 111 | ---- 112 | bind "v" 113 | 114 | context code 115 | 116 | template function :blank :indent 117 | "Nested functions are indented." 118 | ---- 119 | function {{?NAME}} 120 | {{^}} 121 | end 122 | ---- 123 | bind "f" 124 | 125 | template variable :blank :indent 126 | "Template to declare a variable." 127 | ---- 128 | persistent {{?NAME}} 129 | ---- 130 | bind "v" 131 | 132 | 133 | ;; end -------------------------------------------------------------------------------- /tlc.el: -------------------------------------------------------------------------------- 1 | ;;; tlc --- Major mode for editing tlc files 2 | ;; 3 | ;; Author: Eric M. Ludlam 4 | ;; Keywords: tlc 5 | ;; X-Abstract: Major mode for editing tlc files 6 | ;; Version: 7 | 8 | (defvar tlc-version "1.2" 9 | "The current version of TLC mode.") 10 | 11 | ;; 12 | ;; Copyright 1997-2005 The MathWorks, Inc. 13 | ;; 14 | ;; This program is derived from free software; you can redistribute it 15 | ;; and/or modify it under the terms of the GNU General Public License 16 | ;; as published by the Free Software Foundation; either version 2, or 17 | ;; (at your option) any later version. 18 | ;; 19 | ;; This program is distributed in the hope that it will be useful, 20 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | ;; GNU General Public License for more details. 23 | ;; 24 | ;; You should have received a copy of the GNU General Public License 25 | ;; along with GNU Emacs; see the file COPYING. If not, write to 26 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 27 | ;; 28 | ;;; Commentary: 29 | ;; 30 | ;; This is a major mode for editing Target Language Compiler scripts. 31 | ;; It automatically indents the programming constructs. 32 | ;; 33 | 34 | ;;; History: 35 | ;; 36 | ;; 10Sep1998 by Eric M. Ludlam 37 | ;; Posted First revision onto the FTP site. 38 | ;; 39 | ;; 06Oct2005 Peter S galbraith 40 | ;; Minor changes for: 41 | ;; - support customization. 42 | ;; - added autoload cookies. 43 | ;; - CVS storage elsewhere without changing the version number. 44 | ;; 45 | ;; Add history items to the ChangeLog. 46 | 47 | ;;; Code: 48 | (defun tlc-version () 49 | "Display the current version of TLC mode." 50 | (interactive) 51 | (message tlc-version)) 52 | 53 | (defgroup tlc nil 54 | "Major mode for editing tlc files." 55 | :group 'languages) 56 | 57 | (defvar tlc-syntax-table nil 58 | "Syntax table used in an TLC file.") 59 | 60 | (unless tlc-syntax-table 61 | (setq tlc-syntax-table (make-syntax-table (standard-syntax-table))) 62 | (modify-syntax-entry ?/ ". 14" tlc-syntax-table) 63 | (modify-syntax-entry ?% ". 2356" tlc-syntax-table) 64 | (modify-syntax-entry ?\n "> b" tlc-syntax-table) 65 | (modify-syntax-entry ?\" "\"" tlc-syntax-table) 66 | (modify-syntax-entry ?< "(>" tlc-syntax-table) 67 | (modify-syntax-entry ?> ")>" tlc-syntax-table) 68 | ) 69 | 70 | (defvar tlc-mode-map 71 | (let ((km (make-sparse-keymap))) 72 | (define-key km "\C-m" 'tlc-return) 73 | (define-key km [return] 'tlc-return) 74 | (define-key km "\C-i" 'tlc-indent) 75 | km) 76 | "Keymap for `tlc-mode'.") 77 | 78 | (defvar tlc-font-lock-output-code 'tlc-font-lock-output-code 79 | "Face for output code.") 80 | 81 | (defface tlc-font-lock-output-code 82 | '((((class grayscale) (background light)) 83 | (:foreground "DimGray" :underline t)) 84 | (((class grayscale) (background dark)) 85 | (:foreground "LightGray" :underline t)) 86 | (((class color) (background light)) (:foreground "DarkGreen")) 87 | (((class color) (background dark)) (:foreground "chartreuse")) 88 | (t (:underline t))) 89 | "Font Lock mode face used to highlight tlc keywords." 90 | :group 'tlc) 91 | 92 | (defcustom tlc-keywords 93 | '("CAST" "EXISTS" "FEVAL" "FILE_EXISTS" "FORMAT" 94 | "FIELDNAMES" "GETFIELD" "GENERATE" 95 | "GENERATE_FILENAME" "GENERATE_FORMATTED_VALUE" 96 | "GENERATE_FUNCTION_EXISTS" "GENERATE_TYPE" 97 | "GENERATE_TYPE_FUNCTION_EXISTS" "GET_COMMAND_SWITCH" 98 | "IDNUM" "IMAG" 99 | "INT8MAX" "INT8MIN" 100 | "INT16MAX" "INT16MIN" 101 | "INT32MAX" "INT32MIN" 102 | "ISEQUAL" "ISFIELD" "ISINF" "ISNAN" "ISFINITE" 103 | "NULL_FILE" "NUMTLCFILES" 104 | "OUTPUT_LINES" "SIZE" "STDOUT" "STRING" "STRINGOF" 105 | "SYSNAME" "TLCFILES" "TLC_TIME" 106 | "TLC_FALSE" "TLC_TRUE" 107 | "TLC_VERSION" "TYPE" 108 | "UINT8MAX" "UINT16MAX" "UINT32MAX" 109 | "UINTWHITE_SPACE" "WILL_ROLL") 110 | "Keywords to highlight in TLC." 111 | :type '(repeat (string :tag "keyword")) 112 | :group 'tlc) 113 | 114 | (defvar tlc-font-lock-keywords 115 | (list 116 | ;; Some keywords 117 | '("^%function\\s-+\\(\\sw+\\)\\s-*(" 1 font-lock-function-name-face) 118 | '("^%function\\s-+\\(\\sw+\\)\\s-*(" 119 | ("\\s-*\\(\\sw+\\)\\s-*[,)]" nil nil 120 | (1 font-lock-variable-name-face))) 121 | '("\\(%%[^\n]*\\)\n" 1 font-lock-comment-face prepend) 122 | '("\\(^[ \t]*\\([^ \n\t%]\\|%<\\)[^\n]*\\)$" 1 tlc-font-lock-output-code append) 123 | '("\\(^\\|\\s-\\)\\(%[^% \t(\n>]+\\)\\>" 2 font-lock-keyword-face) 124 | '("%assign\\s-+:*\\([_a-zA-Z0-9.]+\\)\\s-*\\($\\|=\\)" 1 font-lock-variable-name-face) 125 | '("%\\(exit\\|warning\\|error\\|trace\\) \\([^\n]+\\)$" 2 font-lock-string-face prepend) 126 | '("\\(%<[^%\n>]+>\\)" 1 font-lock-reference-face prepend) 127 | (list (concat "\\<\\(" (regexp-opt tlc-keywords) "\\)\\>") 128 | 1 'font-lock-type-face) 129 | '("[^.]\\(\\.\\.\\.\\)$" 1 'underline prepend) 130 | ) 131 | "List of keywords for nicely coloring X defaults.") 132 | 133 | ;;;###autoload 134 | (defun tlc-mode () 135 | "Major mode for editing Tlc files, or files found in tlc directories." 136 | (interactive) 137 | (kill-all-local-variables) 138 | (setq major-mode 'tlc-mode) 139 | (setq mode-name "TLC") 140 | (use-local-map tlc-mode-map) 141 | (set-syntax-table tlc-syntax-table) 142 | (make-variable-buffer-local 'comment-start-skip) 143 | (make-local-variable 'comment-start) 144 | (make-local-variable 'comment-end) 145 | (make-local-variable 'comment-column) 146 | (make-local-variable 'comment-start-skip) 147 | (make-local-variable 'comment-multi-line) 148 | (setq comment-start "/% " 149 | comment-end " %/" 150 | comment-multi-line t) 151 | (setq comment-start-skip "%%\\|/%") 152 | (make-variable-buffer-local 'font-lock-comment-start-regexp) 153 | (make-local-variable 'indent-line-function) 154 | (setq indent-line-function 'tlc-indent) 155 | (make-local-variable 'font-lock-defaults) 156 | (setq font-lock-defaults '((tlc-font-lock-keywords 157 | ) 158 | nil ; do not do string/comment highlighting 159 | nil ; keywords are case sensitive. 160 | ;; This puts _ as a word constituant, 161 | ;; simplifying our keywords significantly 162 | ((?_ . "w")))) 163 | (tlc-version) 164 | ) 165 | 166 | (defun tlc-return () 167 | "Handle carriage return in `tlc-mode'." 168 | (interactive) 169 | (newline) 170 | (tlc-indent)) 171 | 172 | (defun tlc-indent () 173 | "Indent the current line to the indentation of the previous line." 174 | (interactive) 175 | (beginning-of-line) 176 | (delete-horizontal-space) 177 | (indent-to (tlc-calc-indentation)) 178 | ) 179 | 180 | (defun tlc-calc-indentation () 181 | "Calculate the indentation of this line." 182 | (beginning-of-line) 183 | (let ((i (cond 184 | ((looking-at 185 | "\\s-*\\(\\(\\(%end\\(roll\\|with\\|if\\|for\\|\ 186 | foreach\\|while\\|function\\)\\|%else\\|%elseif\\|%case\\|%default\\)\\>\\)\ 187 | \\|}\\)") 188 | -2) 189 | ((looking-at "\\s-*%/") 190 | -1) 191 | ((looking-at "\\s-*%endswitch") 192 | -4) 193 | (t 0))) 194 | (percent (looking-at "\\s-*%")) 195 | (percent-slash (looking-at "\\s-*%/")) 196 | (percent-percent (looking-at "\\s-*%%")) 197 | (indent-because-of-continuation nil)) 198 | 199 | (if (bobp) (current-indentation) 200 | (save-excursion 201 | (forward-line -1) 202 | (beginning-of-line) 203 | (while (and (looking-at "^\\s-*$") (not (bobp))) (forward-line -1)) 204 | (cond ((bobp) nil) 205 | ((and percent (looking-at "\\s-*/%")) 206 | (setq i (+ (current-indentation) 1))) 207 | ((and percent-slash (tlc-in-multiline-comment) 208 | (looking-at "\\s-*%")) 209 | (setq i (+ (current-indentation) 0))) 210 | (t 211 | (let* ((nexti (tlc-calc-next-indentation))) 212 | (setq i (+ (current-indentation) 213 | (if (and indent-because-of-continuation 214 | (or (> 0 i) percent-percent)) 215 | i 216 | (+ i nexti))))) 217 | (if (< i 0) (setq i 0)))) 218 | i)))) 219 | 220 | (defun tlc-calc-next-indentation () 221 | "Calc how much more to indent the next line." 222 | (+ 223 | (cond ((save-excursion 224 | (and (not (tlc-assignment-continuation-p)) 225 | (tlc-beginning-of-statement)) 226 | (looking-at "\\s-*\\(\\(%\\(case\\|roll\\|with\\|if\\|for\\|\ 227 | foreach\\|while\\|else\\|elseif\\|default\\|function\\)\\>\\)\\|/%\\)")) 228 | 2) 229 | ((looking-at "\\s-*%/") 230 | -1) 231 | ((looking-at "\\s-*\\(%switch\\)\\>") 232 | 4) 233 | ;((looking-at "\\s-*%break\\>") 234 | ; -2) 235 | ((and (save-excursion (end-of-line) 236 | (or (tlc-assignment-continuation-p) 237 | (progn (forward-char -3) 238 | (looking-at "\\\\$")))) 239 | (save-excursion (forward-line -1) 240 | (end-of-line) 241 | (not 242 | (or (tlc-assignment-continuation-p) 243 | (progn (forward-char -3) 244 | (looking-at "\\\\$")))))) 245 | (setq indent-because-of-continuation t) 246 | 2) 247 | ((or (save-excursion (end-of-line) 248 | (= (preceding-char) ?{)) 249 | ) 250 | 2) 251 | (t 0)) 252 | (if (and (not (tlc-line-special)) 253 | (not (save-excursion (end-of-line) 254 | (or (tlc-assignment-continuation-p) 255 | (progn (forward-char -3) 256 | (looking-at "\\\\$"))))) 257 | (save-excursion (forward-line -1) 258 | (end-of-line) 259 | (or (tlc-assignment-continuation-p) 260 | (progn (forward-char -3) 261 | (looking-at "\\\\$"))))) 262 | -2 263 | 0))) 264 | 265 | (defun tlc-beginning-of-statement () 266 | "Goto the beginning of a statement, skipping over continuation lines." 267 | (beginning-of-line) 268 | (if (not (save-excursion (forward-line -1) (tlc-assignment-continuation-p))) 269 | nil 270 | (forward-line -1) 271 | (while (tlc-assignment-continuation-p) 272 | (forward-line -1)) 273 | (forward-line 1) 274 | (beginning-of-line))) 275 | 276 | (defun tlc-line-special () 277 | "Return t if the current line is a special language line." 278 | (save-excursion 279 | (save-match-data 280 | (beginning-of-line) 281 | (looking-at "\\s-*\\(%[^<]\\|}\\)")))) 282 | 283 | (defun tlc-assignment-continuation-p () 284 | "See if continuation lines should be indented." 285 | (save-excursion 286 | (beginning-of-line) 287 | (and (progn (end-of-line) (forward-char -3) (looking-at "\\.\\.\\."))))) 288 | 289 | (defun tlc-in-multiline-comment () 290 | "Return t we are in a multiline comment." 291 | (save-excursion 292 | (save-match-data 293 | (if (re-search-backward "/%\\|%/" nil t) 294 | (if (looking-at "/%") 295 | t 296 | nil) 297 | nil)))) 298 | 299 | ;;; Add to mode list 300 | ;;;###autoload(add-to-list 'auto-mode-alist '("\\.tlc$" .tlc-mode)) 301 | (add-to-list 'auto-mode-alist '("\\.tlc$" .tlc-mode)) 302 | 303 | (provide 'tlc) 304 | 305 | ;;; tlc.el ends here 306 | -------------------------------------------------------------------------------- /toolbox/Makefile: -------------------------------------------------------------------------------- 1 | # Automatically Generated Makefile by EDE. 2 | # For use with: make 3 | # Relative File Name: toolbox/Makefile 4 | # 5 | # DO NOT MODIFY THIS FILE OR YOUR CHANGES MAY BE LOST. 6 | # EDE is the Emacs Development Environment. 7 | # http://cedet.sourceforge.net/ede.shtml 8 | # 9 | 10 | top=../ 11 | ede_FILES=Project.ede Makefile 12 | 13 | matlab_MISC=emacsinit.m opentoline.m emacsdocomplete.m 14 | VERSION=3.3.2 15 | DISTDIR=$(top)matlab-emacs-$(VERSION)/toolbox 16 | 17 | 18 | 19 | all: matlab 20 | 21 | matlab: 22 | @ 23 | 24 | tags: 25 | 26 | .PHONY: dist 27 | 28 | dist: 29 | mkdir $(DISTDIR) 30 | cp $(matlab_MISC) $(ede_FILES) $(DISTDIR) 31 | 32 | Makefile: Project.ede 33 | @echo Makefile is out of date! It needs to be regenerated by EDE. 34 | @echo If you have not modified Project.ede, you can use 'touch' to update the Makefile time stamp. 35 | @false 36 | 37 | 38 | 39 | # End of Makefile 40 | -------------------------------------------------------------------------------- /toolbox/Project.ede: -------------------------------------------------------------------------------- 1 | ;; Object toolbox 2 | ;; EDE Project Files are auto generated: Do Not Edit 3 | (ede-proj-project "toolbox" 4 | :file "Project.ede" 5 | :name "toolbox" 6 | :targets 7 | (list 8 | (ede-proj-target-makefile-miscelaneous "matlab" 9 | :name "matlab" 10 | :path "" 11 | :source '("emacsinit.m" "opentoline.m" "emacsdocomplete.m")))) 12 | -------------------------------------------------------------------------------- /toolbox/emacsdocomplete.m: -------------------------------------------------------------------------------- 1 | function emacsdocomplete(substring) 2 | % Ask for completions of SUBSTRING from MATLAB. 3 | % This is used by Emacs TAB in matlab-shell to provide possible 4 | % completions. This hides the differences between versions 5 | % for the calls needed to do completions. 6 | 7 | v = ver('MATLAB'); 8 | 9 | 10 | if str2double(v.Version) < 8.4 11 | 12 | % Pre R2014b: partial_string 13 | extracmd = ''; 14 | 15 | else 16 | 17 | % Post R2014b: partial_string, caret, num 18 | extracmd = [ ', ' num2str(length(substring)) ',0' ]; 19 | 20 | % DEV NOTE: If you find a test failure, contact Eric Ludlam 21 | % to also update matlab-emacs SF repository. 22 | 23 | end 24 | 25 | command = [ 'matlabMCRprocess_emacs = com.mathworks.jmi.MatlabMCR;' ... 26 | 'emacs_completions_output = matlabMCRprocess_emacs.mtFindAllTabCompletions(''' ... 27 | substring '''' extracmd '),' ... 28 | 'clear(''matlabMCRprocess_emacs'',''emacs_completions_output'');' ]; 29 | 30 | % Completion engine needs to run in the base workspace to know 31 | % what the variables you have to work with are. 32 | evalin('base',command); 33 | 34 | end -------------------------------------------------------------------------------- /toolbox/emacsinit.m: -------------------------------------------------------------------------------- 1 | function emacsinit(clientcommand) 2 | % EMACSINIT Initialize the current MATLAB session for matlab-shell-mode 3 | 4 | if usejava('jvm') 5 | % Disable built-in editor showing up for debugging 6 | com.mathworks.services.Prefs.setBooleanPref('EditorGraphicalDebugging', false); 7 | % Disable the built-in editor for normal editing 8 | com.mathworks.services.Prefs.setBooleanPref('EditorBuiltinEditor', false); 9 | % Use emacsclient no-wait to send edit requests to a 10 | % running emacs. 11 | if nargin == 0 12 | clientcommand = 'emacsclient -n'; 13 | end 14 | com.mathworks.services.Prefs.setStringPref('EditorOtherEditor', clientcommand); 15 | end 16 | 17 | % Use the desktop hotlinking system in MATLAB Shell. matlab-shell 18 | % will interpret them, and provide clickable areas. 19 | % NOTE: This doesn't work in all cases where HotLinks are used. 20 | feature('HotLinks','on'); 21 | end -------------------------------------------------------------------------------- /toolbox/opentoline.m: -------------------------------------------------------------------------------- 1 | function opentoline(file, line, column) 2 | %OPENTOLINE Open to specified line in function file in Emacs. 3 | % This is a hack to override the built-in opentoline program in MATLAB. 4 | % 5 | % Remove this M file from your path to get the old behavior. 6 | 7 | editor = system_dependent('getpref', 'EditorOtherEditor'); 8 | editor = editor(2:end); 9 | 10 | if nargin==3 11 | linecol = sprintf('+%d:%d',line,column); 12 | else 13 | linecol = sprintf('+%d',line); 14 | end 15 | 16 | if ispc 17 | % On Windows, we need to wrap the editor command in double quotes 18 | % in case it contains spaces 19 | system(['"' editor '" "' linecol '" "' file '"&']); 20 | else 21 | % On UNIX, we don't want to use quotes in case the user's editor 22 | % command contains arguments (like "xterm -e vi") 23 | system([editor ' "' linecol '" "' file '" &']); 24 | end 25 | end 26 | --------------------------------------------------------------------------------