aboutsummaryrefslogtreecommitdiffstats
path: root/elpa/lsp-mode-20220505.630/lsp-vhdl.el
blob: aa55e0ebacd4bd6952a362cc45430a37c5daaeab (plain) (blame)
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
;;; lsp-vhdl.el --- VHDL Client settings         -*- lexical-binding: t; -*-

;; Copyright (C) 2019 Christian Birk Sørensen

;; Author: Christian Birk Sørensen <chrbirks+emacs@gmail.com>
;; Created: 6 October 2019
;; Keywords: languages, lsp, vhdl

;; 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 <https://www.gnu.org/licenses/>.

;;; Commentary:

;; LSP support for VHDL using using an external language server. Currently
;; the supported servers are:
;;
;; VHDL-tool. See http://www.vhdltool.com/configuration for setting up the
;; project file.
;;
;; HDL Checker. See https://github.com/suoto/hdl_checker/wiki/setting-up-a-project
;; for setting up the project file.
;;
;; VHDL LS. See https://github.com/kraigher/rust_hdl#configuration for setting
;; up the project file.
;;
;; GHDL LS. See https://github.com/ghdl/ghdl-language-server for setting up the
;; project file.
;;
;; Set the symbol lsp-vhdl-server to select the language server and set
;; lsp-vhdl-server-path if the binary is not in the user PATH.

;;; Code:

(require 'lsp-mode)

(defvar vhdl-tool-bin-name "vhdl-tool"
  "Name of the VHDL Tool binary.")

(defvar hdl-checker-bin-name "hdl_checker"
  "Name of HDL Checker binary.")

(defvar vhdl-ls-bin-name "vhdl_ls"
  "Name of the VHDL LS binary.")

(defvar ghdl-ls-bin-name "ghdl-ls"
  "Name of the GHDL LS binary.")

(defgroup lsp-vhdl nil
  "LSP support for VHDL. Set lsp-vhdl-server to select server. The default is to use VHDL-tool."
  :group 'lsp-mode)

(defcustom lsp-vhdl-server 'vhdl-tool
  "Select which server to use:
VHDL-tool: A syntax checking, type checking and linting tool (http://vhdltool.com).
HDL Checker: A wrapper for third party tools such as GHDL, ModelSim, Vivado Simulator (https://github.com/suoto/hdl_checker).
VHDL LS: A complete VHDL language server protocol implementation with diagnostics, navigate to symbol, find all references etc. (https://github.com/kraigher/rust_hdl)."
  :type '(choice (const :tag "VHDL-tool" vhdl-tool)
		 (const :tag "HDL Checker" hdl-checker)
		 (const :tag "VHDL LS" vhdl-ls)
		 (const :tag "GHDL LS" ghdl-ls))
  :group 'lsp-vhdl)

(defcustom lsp-vhdl-server-path nil
  "Path to binary server file."
  :group 'lsp-vhdl
  :risky t
  :type 'file)

(defvar lsp-vhdl--params nil)

(defun lsp-vhdl--create-connection ()
  "Returns lsp-stdio-connection based on the selected server"
  (lsp-vhdl--set-server-path)
  (lsp-vhdl--set-server-args)
  (lsp-stdio-connection
    (lambda () (cons (plist-get lsp-vhdl--params 'server-path) (plist-get lsp-vhdl--params 'server-args)))
    (lambda () (executable-find (plist-get lsp-vhdl--params 'server-path)))))

(defun lsp-vhdl--set-server-path()
  "Set path to server binary based on selection in lsp-vhdl-server."
  (cond ((eq lsp-vhdl-server 'hdl-checker) (if (eq lsp-vhdl-server-path nil)
					       (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path hdl-checker-bin-name))
					     (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path lsp-vhdl-server-path))))
	((eq lsp-vhdl-server 'vhdl-tool) (if (eq lsp-vhdl-server-path nil)
					     (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path vhdl-tool-bin-name))
					   (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path lsp-vhdl-server-path))))
	((eq lsp-vhdl-server 'vhdl-ls) (if (eq lsp-vhdl-server-path nil)
					   (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path vhdl-ls-bin-name))
					 (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path lsp-vhdl-server-path))))
	((eq lsp-vhdl-server 'ghdl-ls) (if (eq lsp-vhdl-server-path nil)
					   (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path ghdl-ls-bin-name))
					 (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-path lsp-vhdl-server-path))))))

(defun lsp-vhdl--set-server-args()
  "Set server arguments based on server selection."
  (cond ((eq lsp-vhdl-server 'hdl-checker) (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-args '("--lsp"))))
	((eq lsp-vhdl-server 'vhdl-tool) (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-args '("lsp"))))
	((eq lsp-vhdl-server 'vhdl-ls) (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-args '())))
	((eq lsp-vhdl-server 'ghdl-ls) (setq lsp-vhdl--params (plist-put lsp-vhdl--params 'server-args '())))))

(lsp-register-client
 (make-lsp-client :new-connection (lsp-vhdl--create-connection)
                  :major-modes '(vhdl-mode)
                  :language-id "VHDL"
                  :priority -1
                  :server-id 'lsp-vhdl))

(lsp-consistency-check lsp-vhdl)

(provide 'lsp-vhdl)
;;; lsp-vhdl.el ends here