diff options
| author | Jim Porter | 2023-03-20 17:25:54 -0700 |
|---|---|---|
| committer | Jim Porter | 2023-03-28 12:03:29 -0700 |
| commit | cde38f0df3fa3540ce411a48d95da1c2f1be1b60 (patch) | |
| tree | 7cf41e920e16da219f6a2bc26dcb803bc2538916 /test | |
| parent | bb088885df7a8e8a32670286a8636db8c6fadcf4 (diff) | |
| download | emacs-cde38f0df3fa3540ce411a48d95da1c2f1be1b60.tar.gz emacs-cde38f0df3fa3540ce411a48d95da1c2f1be1b60.zip | |
Avoid parsing some Eshell forms when performing completion
During completion, we want to evaluate most Eshell forms
(e.g. variable references), but skip others (e.g. globbing,
subcommands). For globbing, we want to pass the literal glob to
Pcomplete so it can use the glob for selecting completion candidates.
For subcommands (including Lisp forms), we especially want to avoid
evaluation, since they can produce arbitary side effects! (Bug#50470)
* lisp/eshell/esh-cmd.el (eshell-allow-commands): New variable...
(eshell-commands-forbidden): New error...
(eshell-named-command, eshell-lisp-command): ... use them.
* lisp/eshell/em-cmpl.el (eshell-complete--eval-argument-form):
Disallow command forms and handle errors ourselves.
(eshell-complete-parse-arguments): Don't parse glob characters.
* test/lisp/eshell/em-cmpl-tests.el
(em-cmpl-test/parse-arguments/unevaluated-subcommand)
(em-cmpl-test/parse-arguments/unevaluated-lisp-form)
(em-cmpl-test/parse-arguments/unevaluated-inner-subcommand)
(em-cmpl-test/file-completion/glob, em-cmpl-test/command-completion)
(em-cmpl-test/subcommand-completion): New tests.
(em-cmpl-test/parse-arguments/pipeline): Remove superfluous
let-binding.
(em-cmpl-test/file-completion/after-list): Use a list variable rather
than a subexpression; the latter is no longer evaluated during
completion.
(em-cmpl-test/lisp-function-completion): Check "$(func)" syntax.
Diffstat (limited to 'test')
| -rw-r--r-- | test/lisp/eshell/em-cmpl-tests.el | 86 |
1 files changed, 76 insertions, 10 deletions
diff --git a/test/lisp/eshell/em-cmpl-tests.el b/test/lisp/eshell/em-cmpl-tests.el index ea907f1945d..29a41625d5e 100644 --- a/test/lisp/eshell/em-cmpl-tests.el +++ b/test/lisp/eshell/em-cmpl-tests.el | |||
| @@ -69,11 +69,10 @@ ACTUAL and EXPECTED should both be lists of strings." | |||
| 69 | (ert-deftest em-cmpl-test/parse-arguments/pipeline () | 69 | (ert-deftest em-cmpl-test/parse-arguments/pipeline () |
| 70 | "Test that parsing arguments for completion discards earlier commands." | 70 | "Test that parsing arguments for completion discards earlier commands." |
| 71 | (with-temp-eshell | 71 | (with-temp-eshell |
| 72 | (let ((eshell-test-value '("foo" "bar"))) | 72 | (insert "echo hi | cat") |
| 73 | (insert "echo hi | cat") | 73 | (should (eshell-arguments-equal |
| 74 | (should (eshell-arguments-equal | 74 | (car (eshell-complete-parse-arguments)) |
| 75 | (car (eshell-complete-parse-arguments)) | 75 | '("cat"))))) |
| 76 | '("cat")))))) | ||
| 77 | 76 | ||
| 78 | (ert-deftest em-cmpl-test/parse-arguments/multiple-dots () | 77 | (ert-deftest em-cmpl-test/parse-arguments/multiple-dots () |
| 79 | "Test parsing arguments with multiple dots like \".../\"." | 78 | "Test parsing arguments with multiple dots like \".../\"." |
| @@ -123,6 +122,45 @@ ACTUAL and EXPECTED should both be lists of strings." | |||
| 123 | (car (eshell-complete-parse-arguments)) | 122 | (car (eshell-complete-parse-arguments)) |
| 124 | '("echo" "foo" "bar")))))) | 123 | '("echo" "foo" "bar")))))) |
| 125 | 124 | ||
| 125 | (ert-deftest em-cmpl-test/parse-arguments/unevaluated-subcommand () | ||
| 126 | "Test that subcommands return a stub when parsing for completion." | ||
| 127 | (with-temp-eshell | ||
| 128 | (insert "echo {echo hi}") | ||
| 129 | (should (eshell-arguments-equal | ||
| 130 | (car (eshell-complete-parse-arguments)) | ||
| 131 | `("echo" ,(propertize | ||
| 132 | "\0" 'eshell-argument-stub 'named-command))))) | ||
| 133 | (with-temp-eshell | ||
| 134 | (insert "echo ${echo hi}") | ||
| 135 | (should (eshell-arguments-equal | ||
| 136 | (car (eshell-complete-parse-arguments)) | ||
| 137 | `("echo" ,(propertize | ||
| 138 | "\0" 'eshell-argument-stub 'named-command)))))) | ||
| 139 | |||
| 140 | (ert-deftest em-cmpl-test/parse-arguments/unevaluated-lisp-form () | ||
| 141 | "Test that Lisp forms return a stub when parsing for completion." | ||
| 142 | (with-temp-eshell | ||
| 143 | (insert "echo (concat \"hi\")") | ||
| 144 | (should (eshell-arguments-equal | ||
| 145 | (car (eshell-complete-parse-arguments)) | ||
| 146 | `("echo" ,(propertize | ||
| 147 | "\0" 'eshell-argument-stub 'lisp-command))))) | ||
| 148 | (with-temp-eshell | ||
| 149 | (insert "echo $(concat \"hi\")") | ||
| 150 | (should (eshell-arguments-equal | ||
| 151 | (car (eshell-complete-parse-arguments)) | ||
| 152 | `("echo" ,(propertize | ||
| 153 | "\0" 'eshell-argument-stub 'lisp-command)))))) | ||
| 154 | |||
| 155 | (ert-deftest em-cmpl-test/parse-arguments/unevaluated-inner-subcommand () | ||
| 156 | "Test that nested subcommands return a stub when parsing for completion." | ||
| 157 | (with-temp-eshell | ||
| 158 | (insert "echo $exec-path[${echo 0}]") | ||
| 159 | (should (eshell-arguments-equal | ||
| 160 | (car (eshell-complete-parse-arguments)) | ||
| 161 | `("echo" ,(propertize | ||
| 162 | "\0" 'eshell-argument-stub 'named-command)))))) | ||
| 163 | |||
| 126 | (ert-deftest em-cmpl-test/file-completion/unique () | 164 | (ert-deftest em-cmpl-test/file-completion/unique () |
| 127 | "Test completion of file names when there's a unique result." | 165 | "Test completion of file names when there's a unique result." |
| 128 | (with-temp-eshell | 166 | (with-temp-eshell |
| @@ -150,14 +188,39 @@ ACTUAL and EXPECTED should both be lists of strings." | |||
| 150 | (forward-line -1) | 188 | (forward-line -1) |
| 151 | (should (looking-at "Complete, but not unique"))))))) | 189 | (should (looking-at "Complete, but not unique"))))))) |
| 152 | 190 | ||
| 191 | (ert-deftest em-cmpl-test/file-completion/glob () | ||
| 192 | "Test completion of file names using a glob." | ||
| 193 | (with-temp-eshell | ||
| 194 | (ert-with-temp-directory default-directory | ||
| 195 | (write-region nil nil (expand-file-name "file.txt")) | ||
| 196 | (write-region nil nil (expand-file-name "file.el")) | ||
| 197 | (should (equal (eshell-insert-and-complete "echo fi*.el") | ||
| 198 | "echo file.el "))))) | ||
| 199 | |||
| 153 | (ert-deftest em-cmpl-test/file-completion/after-list () | 200 | (ert-deftest em-cmpl-test/file-completion/after-list () |
| 154 | "Test completion of file names after previous list arguments. | 201 | "Test completion of file names after previous list arguments. |
| 155 | See bug#59956." | 202 | See bug#59956." |
| 156 | (with-temp-eshell | 203 | (with-temp-eshell |
| 157 | (ert-with-temp-directory default-directory | 204 | (let ((eshell-test-value '("foo" "bar"))) |
| 158 | (write-region nil nil (expand-file-name "file.txt")) | 205 | (ert-with-temp-directory default-directory |
| 159 | (should (equal (eshell-insert-and-complete "echo (list 1 2) fi") | 206 | (write-region nil nil (expand-file-name "file.txt")) |
| 160 | "echo (list 1 2) file.txt "))))) | 207 | (should (equal (eshell-insert-and-complete "echo $eshell-test-value fi") |
| 208 | "echo $eshell-test-value file.txt ")))))) | ||
| 209 | |||
| 210 | (ert-deftest em-cmpl-test/command-completion () | ||
| 211 | "Test completion of command names like \"command\"." | ||
| 212 | (with-temp-eshell | ||
| 213 | (should (equal (eshell-insert-and-complete "listif") | ||
| 214 | "listify ")))) | ||
| 215 | |||
| 216 | (ert-deftest em-cmpl-test/subcommand-completion () | ||
| 217 | "Test completion of command names like \"{command}\"." | ||
| 218 | (with-temp-eshell | ||
| 219 | (should (equal (eshell-insert-and-complete "{ listif") | ||
| 220 | "{ listify "))) | ||
| 221 | (with-temp-eshell | ||
| 222 | (should (equal (eshell-insert-and-complete "echo ${ listif") | ||
| 223 | "echo ${ listify ")))) | ||
| 161 | 224 | ||
| 162 | (ert-deftest em-cmpl-test/lisp-symbol-completion () | 225 | (ert-deftest em-cmpl-test/lisp-symbol-completion () |
| 163 | "Test completion of Lisp forms like \"#'symbol\" and \"`symbol\". | 226 | "Test completion of Lisp forms like \"#'symbol\" and \"`symbol\". |
| @@ -174,7 +237,10 @@ See <lisp/eshell/esh-cmd.el>." | |||
| 174 | See <lisp/eshell/esh-cmd.el>." | 237 | See <lisp/eshell/esh-cmd.el>." |
| 175 | (with-temp-eshell | 238 | (with-temp-eshell |
| 176 | (should (equal (eshell-insert-and-complete "echo (eshell/ech") | 239 | (should (equal (eshell-insert-and-complete "echo (eshell/ech") |
| 177 | "echo (eshell/echo")))) | 240 | "echo (eshell/echo"))) |
| 241 | (with-temp-eshell | ||
| 242 | (should (equal (eshell-insert-and-complete "echo $(eshell/ech") | ||
| 243 | "echo $(eshell/echo")))) | ||
| 178 | 244 | ||
| 179 | (ert-deftest em-cmpl-test/special-ref-completion/type () | 245 | (ert-deftest em-cmpl-test/special-ref-completion/type () |
| 180 | "Test completion of the start of special references like \"#<buffer\". | 246 | "Test completion of the start of special references like \"#<buffer\". |