-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcompany-matlab-shell.el
102 lines (88 loc) · 4.14 KB
/
company-matlab-shell.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
;;; company-matlab-shell.el --- a matlab-shell-mode completion back-end for MATLAB -*- lexical-binding: t -*-
;; Copyright (C) 2024 Free Software Foundation, Inc.
;; Author: Eric Ludlam <zappo@gnu.org>
;; David Engster <dengste@eml.cc>
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License
;; as published by the Free Software Foundation; either version 3
;; of the License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;;; Code:
(condition-case nil
(require 'company)
(error nil))
(require 'cl-macs)
(require 'matlab)
(require 'matlab-shell)
(defvar company-matlab-shell--ci (make-hash-table :test 'equal)
"Private variable for `company-matlab-shell' completion info.")
(defun company-matlab-shell-grab-completion-substr ()
"Return the completion substring of the command.
The completion substring is to be completed in `matlab-shell', or
\\='stop if completions can't be performed at the current point."
(when (eq major-mode 'matlab-shell-mode)
(if (not (matlab-on-prompt-p))
'stop ;; tell company can't complete when point is not in the prompt
(let ((lastcmd (buffer-substring (point) (line-end-position))))
;; Kill the rest of the line since completion only works at the end of the line and
;; we'd like it to complete within a line. For example,
;; h=figure;
;; h.set('Vis','on')
;; ^
;; TAB here results in:
;; h.set('Visible','on')
(delete-region (point) (line-end-position))
(let* ((buf-name (buffer-name (current-buffer)))
(ci (matlab-shell-get-completion-info))
(common-substr (cdr (assoc 'common-substr ci)))
(did-completion (cdr (assoc 'did-completion ci))))
;; restore the killed part of the line
(let ((orig-pt (point)))
(insert lastcmd)
(goto-char orig-pt))
;; If did-completion, then matlab-shell-get-completion-info updated the
;; *MATLAB* buffer by deleting text and calling (insert replacement-text), and
;; we have no more completion info.
(if did-completion
;; Tell company to abort completion. This causes "Cannot complete at point" and
;; there doesn't seem to be a way to protect against this message.
nil
(puthash buf-name ci company-matlab-shell--ci)
;; command to be completed
common-substr
))))))
(defun company-matlab-shell-get-completions ()
"Get matlab-shell completions."
(let* ((ci (if (eq major-mode 'matlab-shell-mode)
(gethash (buffer-name (current-buffer)) company-matlab-shell--ci)))
(completions (if ci (cdr (assoc 'completions ci)))))
(if ci (remhash (buffer-name (current-buffer)) company-matlab-shell--ci))
(mapcar 'car completions)))
;;;###autoload
(defun company-matlab-shell (command &optional arg &rest ignored)
"A `company-mode' completion backend for `matlab-shell'.
COMMAND is the item to complete.
ARG and IGNORED are ignored."
(interactive (list 'interactive))
(ignore arg ignored)
(cl-case command
( interactive (if (fboundp 'company-begin-backend) ;; quiet warning when no company
(company-begin-backend 'company-matlab-shell)
(error "Unable to provide completions - company-begin-backend is missing")))
( prefix (company-matlab-shell-grab-completion-substr))
( candidates (company-matlab-shell-get-completions))
( sorted t)))
(provide 'company-matlab-shell)
;;; company-matlab-shell.el ends here
;; LocalWords: Ludlam Engster ci defun substr lastcmd eol buf cdr puthash gethash remhash mapcar
;; LocalWords: fboundp