Fortran · 8633 bytes Raw Blame History
1 module server_detection_module
2 implicit none
3 private
4
5 public :: detected_server_t
6 public :: detect_all_servers, check_server_installed
7 public :: get_known_servers_count
8
9 integer, parameter :: MAX_SERVERS = 30
10
11 type :: detected_server_t
12 character(len=64) :: name = '' ! "pyright", "clangd", etc.
13 character(len=32) :: language = '' ! "python", "c", etc.
14 character(len=256) :: install_cmd = '' ! "pip install pyright"
15 character(len=256) :: description = '' ! "Python type checker and language server"
16 character(len=128) :: check_cmd = '' ! Command to check if installed
17 logical :: is_installed = .false. ! Result of detection
18 character(len=64) :: version = '' ! Detected version (if installed)
19 end type detected_server_t
20
21 contains
22
23 function get_known_servers_count() result(count)
24 integer :: count
25 count = 20 ! Number of servers we know about
26 end function get_known_servers_count
27
28 subroutine detect_all_servers(servers, num_servers)
29 type(detected_server_t), intent(out), allocatable :: servers(:)
30 integer, intent(out) :: num_servers
31 integer :: i
32
33 num_servers = get_known_servers_count()
34 allocate(servers(num_servers))
35
36 ! Initialize all known servers
37 call init_known_servers(servers)
38
39 ! Check which are installed
40 do i = 1, num_servers
41 servers(i)%is_installed = check_server_installed(servers(i)%check_cmd)
42 end do
43 end subroutine detect_all_servers
44
45 subroutine init_known_servers(servers)
46 type(detected_server_t), intent(inout) :: servers(:)
47 integer :: i
48
49 i = 1
50
51 ! Python - Pyright
52 servers(i)%name = 'pyright'
53 servers(i)%language = 'Python'
54 servers(i)%install_cmd = 'pipx install pyright'
55 servers(i)%description = 'Python type checker and language server'
56 servers(i)%check_cmd = 'pyright-langserver'
57 i = i + 1
58
59 ! Python - Ruff
60 servers(i)%name = 'ruff'
61 servers(i)%language = 'Python'
62 servers(i)%install_cmd = 'pipx install ruff'
63 servers(i)%description = 'Fast Python linter with auto-fix'
64 servers(i)%check_cmd = 'ruff'
65 i = i + 1
66
67 ! Python - python-lsp-server
68 servers(i)%name = 'python-lsp-server'
69 servers(i)%language = 'Python'
70 servers(i)%install_cmd = 'pipx install python-lsp-server'
71 servers(i)%description = 'Python LSP (pylsp) with plugins support'
72 servers(i)%check_cmd = 'pylsp'
73 i = i + 1
74
75 ! C/C++ - clangd
76 servers(i)%name = 'clangd'
77 servers(i)%language = 'C/C++'
78 servers(i)%install_cmd = 'brew install llvm'
79 servers(i)%description = 'C/C++ language server from LLVM'
80 servers(i)%check_cmd = 'clangd'
81 i = i + 1
82
83 ! Rust - rust-analyzer
84 servers(i)%name = 'rust-analyzer'
85 servers(i)%language = 'Rust'
86 servers(i)%install_cmd = 'rustup component add rust-analyzer'
87 servers(i)%description = 'Rust language server'
88 servers(i)%check_cmd = 'rust-analyzer'
89 i = i + 1
90
91 ! Go - gopls
92 servers(i)%name = 'gopls'
93 servers(i)%language = 'Go'
94 servers(i)%install_cmd = 'go install golang.org/x/tools/gopls@latest'
95 servers(i)%description = 'Go language server'
96 servers(i)%check_cmd = 'gopls'
97 i = i + 1
98
99 ! TypeScript/JavaScript - typescript-language-server
100 servers(i)%name = 'typescript-language-server'
101 servers(i)%language = 'JS/TS'
102 servers(i)%install_cmd = 'npm install -g typescript-language-server typescript'
103 servers(i)%description = 'JavaScript and TypeScript language server'
104 servers(i)%check_cmd = 'typescript-language-server'
105 i = i + 1
106
107 ! JavaScript/TypeScript - vtsls (faster alternative)
108 servers(i)%name = 'vtsls'
109 servers(i)%language = 'JS/TS'
110 servers(i)%install_cmd = 'npm install -g @vtsls/language-server'
111 servers(i)%description = 'Fast TypeScript language server'
112 servers(i)%check_cmd = 'vtsls'
113 i = i + 1
114
115 ! Lua - lua-language-server
116 servers(i)%name = 'lua-language-server'
117 servers(i)%language = 'Lua'
118 servers(i)%install_cmd = 'brew install lua-language-server'
119 servers(i)%description = 'Lua language server by sumneko'
120 servers(i)%check_cmd = 'lua-language-server'
121 i = i + 1
122
123 ! Ruby - solargraph
124 servers(i)%name = 'solargraph'
125 servers(i)%language = 'Ruby'
126 servers(i)%install_cmd = 'gem install solargraph'
127 servers(i)%description = 'Ruby language server'
128 servers(i)%check_cmd = 'solargraph'
129 i = i + 1
130
131 ! Java - jdtls
132 servers(i)%name = 'jdtls'
133 servers(i)%language = 'Java'
134 servers(i)%install_cmd = 'brew install jdtls'
135 servers(i)%description = 'Eclipse JDT Language Server'
136 servers(i)%check_cmd = 'jdtls'
137 i = i + 1
138
139 ! HTML/CSS/JSON - vscode-langservers-extracted
140 servers(i)%name = 'vscode-langservers'
141 servers(i)%language = 'HTML/CSS/JSON'
142 servers(i)%install_cmd = 'npm i -g vscode-langservers-extracted'
143 servers(i)%description = 'HTML, CSS, JSON language servers'
144 servers(i)%check_cmd = 'vscode-html-language-server'
145 i = i + 1
146
147 ! Bash - bash-language-server
148 servers(i)%name = 'bash-language-server'
149 servers(i)%language = 'Bash'
150 servers(i)%install_cmd = 'npm i -g bash-language-server'
151 servers(i)%description = 'Bash/Shell language server'
152 servers(i)%check_cmd = 'bash-language-server'
153 i = i + 1
154
155 ! YAML - yaml-language-server
156 servers(i)%name = 'yaml-language-server'
157 servers(i)%language = 'YAML'
158 servers(i)%install_cmd = 'npm i -g yaml-language-server'
159 servers(i)%description = 'YAML language server'
160 servers(i)%check_cmd = 'yaml-language-server'
161 i = i + 1
162
163 ! Docker - dockerfile-language-server
164 servers(i)%name = 'dockerfile-langserver'
165 servers(i)%language = 'Docker'
166 servers(i)%install_cmd = 'npm i -g dockerfile-language-server-nodejs'
167 servers(i)%description = 'Dockerfile language server'
168 servers(i)%check_cmd = 'docker-langserver'
169 i = i + 1
170
171 ! Zig - zls
172 servers(i)%name = 'zls'
173 servers(i)%language = 'Zig'
174 servers(i)%install_cmd = 'brew install zls'
175 servers(i)%description = 'Zig language server'
176 servers(i)%check_cmd = 'zls'
177 i = i + 1
178
179 ! Swift - sourcekit-lsp
180 servers(i)%name = 'sourcekit-lsp'
181 servers(i)%language = 'Swift'
182 servers(i)%install_cmd = '# Included with Xcode'
183 servers(i)%description = 'Swift/Obj-C language server'
184 servers(i)%check_cmd = 'sourcekit-lsp'
185 i = i + 1
186
187 ! Haskell - haskell-language-server
188 servers(i)%name = 'haskell-language-server'
189 servers(i)%language = 'Haskell'
190 servers(i)%install_cmd = 'ghcup install hls'
191 servers(i)%description = 'Haskell language server'
192 servers(i)%check_cmd = 'haskell-language-server-wrapper'
193 i = i + 1
194
195 ! Terraform - terraform-ls
196 servers(i)%name = 'terraform-ls'
197 servers(i)%language = 'Terraform'
198 servers(i)%install_cmd = 'brew install hashicorp/tap/terraform-ls'
199 servers(i)%description = 'Terraform language server'
200 servers(i)%check_cmd = 'terraform-ls'
201 i = i + 1
202
203 ! Fortran - fortls
204 servers(i)%name = 'fortls'
205 servers(i)%language = 'Fortran'
206 servers(i)%install_cmd = 'pipx install fortls'
207 servers(i)%description = 'Fortran language server'
208 servers(i)%check_cmd = 'fortls'
209 end subroutine init_known_servers
210
211 function check_server_installed(cmd_name) result(installed)
212 character(len=*), intent(in) :: cmd_name
213 logical :: installed
214 character(len=512) :: check_command
215 integer :: exit_status
216
217 installed = .false.
218 if (len_trim(cmd_name) == 0) return
219
220 ! Use 'which' on Unix to check if command exists
221 ! Redirect output to /dev/null to suppress it
222 check_command = 'which ' // trim(cmd_name) // ' > /dev/null 2>&1'
223
224 call execute_command_line(trim(check_command), wait=.true., exitstat=exit_status)
225
226 installed = (exit_status == 0)
227 end function check_server_installed
228
229 end module server_detection_module
230