matlab-complete.el:

(matlab-find-recent-variable-list): Use new search APIs for keyword
searches.
Fix some misc bugs.
(matlab--complete-compute-search-functions):
New - pulled from below:
(matlab-complete-symbol-local):
Remove code for deriving which functions to use.
Pulled out to support testing.

matlab.el:
(matlab-mcos-innerblock-regexp, matlab-mcos-regexp, matlab-block-beg-pre-if)
(matlab-block-beg-pre-no-if, matlab-block-beg-pre): DELETED

tests/metest.el:
(matlab-complete): New require
(metest-all-syntax-tests): Move stuff around.  Add metest-complete-test.
(met-complete-files, met-complete-tools, metest-complete-test): NEW

tests/complete.m:
New file for testing local completion stuff.
This commit is contained in:
Eric Ludlam 2021-03-27 13:58:07 -04:00
parent 2f6958d102
commit 21b33abd51
4 changed files with 139 additions and 70 deletions

View File

@ -248,28 +248,28 @@ If the list is empty, then searches continue backwards through the code."
(nreverse lst)))
(save-excursion
(let ((lst nil))
(while (and (re-search-backward
(concat "\\<\\(" matlab-block-beg-pre-no-if
"\\)\\s-+(?\\s-*\\(" prefix
"\\w+\\)\\>")
bounds t)
(< (length lst) 10))
(setq lst (cons (match-string 2) lst)))
(while (and
(< (length lst) 10)
(matlab-re-search-keyword-backward (matlab-keyword-regex 'ctrl) bounds t))
(when (looking-at (concat "\\w+\\s-+(?\\(" prefix "\\w+\\)\\_>"))
(setq lst (cons (match-string 1) lst))))
(nreverse lst)))
(save-excursion
(if (re-search-backward "^\\s-*global\\s-+" bounds t)
(let ((lst nil) m e)
(let ((lst nil) m e)
(while (matlab-re-search-keyword-backward
(matlab-keyword-regex 'vardecl) bounds t)
(save-excursion
(goto-char (match-end 0))
(while (looking-at "\\(\\w+\\)\\([ \t]+\\|$\\)")
(while (looking-at "\\s-*\\(\\w+\\)\\([ \t]+\\|$\\)")
(setq m (match-string 1)
e (match-end 0))
(if (equal 0 (string-match prefix m))
(setq lst (cons m lst)))
(goto-char e))
(nreverse lst))))
(goto-char e))))
(nreverse lst)))
(save-excursion
(if (and (re-search-backward "^\\s-*function\\>" bounds t)
(re-search-forward "\\<\\(\\w+\\)("
(re-search-forward "\\_<\\(\\w+\\)\\s-*("
(matlab-point-at-eol) t))
(let ((lst nil) m e)
(while (looking-at "\\(\\w+\\)\\s-*[,)]\\s-*")
@ -315,7 +315,7 @@ In NEXT is non-nil, than continue through the list of elements."
(let ((lst nil))
(while (re-search-forward "^\\s-*function\\>" nil t)
(if (re-search-forward
(concat "\\(" prefix "\\w+\\)\\s-*\\($\\|(\\)")
(concat "\\_<\\(" prefix "\\w+\\)\\s-*\\($\\|(\\)")
(matlab-point-at-eol) t)
(setq lst (cons (match-string 1) lst))))
(nreverse lst)))
@ -463,7 +463,33 @@ Use `completion-in-region' to support the completion behavior."
(completion-in-region common-substr-start-pt common-substr-end-pt completions)
))
)
(defun matlab--complete-compute-search-functions (semantics)
"Return the search functions for context specified by SEMATNICS."
(cond ((eq semantics 'solo)
'(matlab-solo-completions
matlab-find-user-functions
matlab-find-recent-variable))
((eq semantics 'boolean)
'(matlab-find-recent-variable
matlab-boolean-completions
matlab-find-user-functions
matlab-value-completions))
((eq semantics 'value)
'(matlab-find-recent-variable
matlab-find-user-functions
matlab-value-completions
matlab-boolean-completions))
((eq semantics 'property)
'(matlab-property-completions
matlab-find-user-functions
matlab-find-recent-variable
matlab-value-completions))
(t '(matlab-find-recent-variable
matlab-find-user-functions
matlab-value-completions
matlab-boolean-completions))))
(defun matlab-complete-symbol-local (&optional arg)
"Complete a partially typed symbol in a MATLAB mode buffer.
If the previously entered command was also `matlab-complete-symbol'
@ -496,29 +522,7 @@ to change it temporarily."
(setq matlab-last-prefix prefix
matlab-last-semantic sem
matlab-completion-search-state
(cond ((eq sem 'solo)
'(matlab-solo-completions
matlab-find-user-functions
matlab-find-recent-variable))
((eq sem 'boolean)
'(matlab-find-recent-variable
matlab-boolean-completions
matlab-find-user-functions
matlab-value-completions))
((eq sem 'value)
'(matlab-find-recent-variable
matlab-find-user-functions
matlab-value-completions
matlab-boolean-completions))
((eq sem 'property)
'(matlab-property-completions
matlab-find-user-functions
matlab-find-recent-variable
matlab-value-completions))
(t '(matlab-find-recent-variable
matlab-find-user-functions
matlab-value-completions
matlab-boolean-completions)))))
(matlab--complete-compute-search-functions sem)))
(cond
((eq matlab-completion-technique 'increment)
(let ((r nil) (donext (eq last-command 'matlab-complete-symbol)))

View File

@ -1447,35 +1447,6 @@ Ignore comments and whitespace."
;;; Regexps for MATLAB language ===============================================
;; "-pre" means "partial regular expression"
;; "-if" and "-no-if" means "[no] Indent Function"
(defconst matlab-mcos-innerblock-regexp "properties\\|methods\\|events\\|enumeration\\|arguments"
"Keywords which mark the beginning of mcos blocks.
These keywords can be overriden as variables or functions in other contexts
asside from that which they declare their content.")
(defconst matlab-mcos-regexp (concat "\\|classdef\\|" matlab-mcos-innerblock-regexp)
"Keywords which mark the beginning of mcos blocks.")
(defconst matlab-block-beg-pre-if
(concat "function\\|parfor\\|spmd\\|for\\|while\\|if\\|switch\\|try"
matlab-mcos-regexp)
"Keywords which mark the beginning of an indented block.
Includes function.")
(defconst matlab-block-beg-pre-no-if
(concat "parfor\\|for\\|spmd\\|while\\|if\\|switch\\|try"
matlab-mcos-regexp)
"Keywords which mark the beginning of an indented block.
Excludes function.")
(defun matlab-block-beg-pre ()
"Partial regular expression to recognize MATLAB block-begin keywords."
(if matlab-functions-have-end
matlab-block-beg-pre-if
matlab-block-beg-pre-no-if))
(defun matlab-match-function-re ()
"Expression to match a function start line.
There are no reliable numeric matches in this expression.

47
tests/complete.m Normal file
View File

@ -0,0 +1,47 @@
function complete (a_arg1, b_arg2)
% This function is for testing completion tools
arguments
a_arg1 (1,1) double
b_arg2 (2,1) int
end
global a_global
global b_global
a_localvar = 1;
b_localvar = 1;
for a_for=1:10
end
if bool_var
end
switch a_switch
end
a_
% @@(solo var "a_localvar" "a_switch" "a_for" "a_global" "a_arg1")
% @@(solo fcn )
% Note: For b, there are other test files the completion
% engine will find, so they are included.
b
% @@(solo fcn "blocal_fcn" "blazy_fcn" "buggy" "blocks")
% @@(solo var "b_localvar" "bool_var" "b_global" "b_arg2")
% quiet mlint
blocal_fcn(a_arg1, b_arg2, a_localvar, b_localvar, a_global, b_global);
end
function blocal_fcn(varargin)
blazy_fcn(varargin{:});
end
function blazy_fcn(varargin)
end

View File

@ -34,6 +34,7 @@
(require 'matlab-load)
(require 'matlab)
(require 'cedet-matlab)
(require 'matlab-complete)
(require 'semantic-matlab)
;; Enable semantic
@ -52,6 +53,7 @@
(setq-default matlab-indent-function-body 'MathWorks-Standard) ;; put it back
(metest-run 'metest-comment-string-syntax-test)
(metest-run 'metest-fontlock-test)
(metest-run 'metest-sexp-counting-test)
(metest-run 'metest-sexp-traversal-test)
@ -61,10 +63,10 @@
(metest-indents-randomize-files)
(metest-run 'metest-indents-test)
;; Parsing and completion are high level tools
(metest-run 'metest-parse-test)
(metest-run 'metest-complete-test)
(metest-run 'metest-fontlock-test)
(metest-log-report (metest-log-write))
(matlab-scan-stats-print)
@ -446,7 +448,52 @@
( "df" . nil )
)
"List of testing keywords and associated faces.")
(defvar met-complete-files '("complete.m")
"List of files for running font completion tests.")
(defvar met-complete-tools '((var . matlab-find-recent-variable)
(fcn . matlab-find-user-functions)
)
"List of tools that generate completions.")
(defvar metest-complete-test (cons "completion" met-complete-files))
(defun metest-complete-test (F)
"Test the completion tools in matlab-complete.el"
(let ((buf (metest-find-file F))
exp act
(cnt 0))
(with-current-buffer buf
(goto-char (point-min))
(while (re-search-forward "%\\s-*@@" nil t)
(setq exp (read (buffer-substring-no-properties (point) (scan-sexps (point) 1))))
;; Move to end of previous line, and try to do a complete
(matlab-with-context-line (matlab-previous-code-line (matlab-compute-line-context 2))
(end-of-line)
(let* ((prefix (buffer-substring-no-properties
(save-excursion (forward-word -1) (point))
(point)))
(sem (matlab-lattr-semantics prefix))
)
;; Did we get the expected semantics of this location?
(when (not (eq sem (car exp)))
(metest-error "Completion Semantic Missmatch: Expected %s but found %s" (car exp) sem))
(let* ((expR (nthcdr 2 exp))
(fcn (assoc (nth 1 exp) met-complete-tools))
(act (funcall (cdr fcn) prefix)))
(when (not (equal act expR))
(metest-error "Completion Missmatch: Expected %S but found %S using function %S"
expR act fcn))
)
))
(setq cnt (1+ cnt))
;; Skip this match, find the next.
(end-of-line)))
(list cnt "tests")))
(defvar met-fontlock-files '("fontlock.m" "mclass.m" "blocks.m")
"List of files for running font lock tests.")