1#!/bin/sh
2
3die () {
4 echo "$*" >&2
5 exit 1
6}
7
8cd "$(dirname "$0")"/../.. ||
9die "Could not cd to top-level directory"
10
11mkdir -p .vscode ||
12die "Could not create .vscode/"
13
14# General settings
15
16cat >.vscode/settings.json.new <<\EOF ||
17{
18 "C_Cpp.intelliSenseEngine": "Default",
19 "C_Cpp.intelliSenseEngineFallback": "Disabled",
20 "[git-commit]": {
21 "editor.wordWrap": "wordWrapColumn",
22 "editor.wordWrapColumn": 72
23 },
24 "[c]": {
25 "editor.detectIndentation": false,
26 "editor.insertSpaces": false,
27 "editor.tabSize": 8,
28 "editor.wordWrap": "wordWrapColumn",
29 "editor.wordWrapColumn": 80,
30 "files.trimTrailingWhitespace": true
31 },
32 "files.associations": {
33 "*.h": "c",
34 "*.c": "c"
35 },
36 "cSpell.ignorePaths": [
37 ],
38 "cSpell.words": [
39 "DATAW",
40 "DBCACHED",
41 "DFCHECK",
42 "DTYPE",
43 "Hamano",
44 "HCAST",
45 "HEXSZ",
46 "HKEY",
47 "HKLM",
48 "IFGITLINK",
49 "IFINVALID",
50 "ISBROKEN",
51 "ISGITLINK",
52 "ISSYMREF",
53 "Junio",
54 "LPDWORD",
55 "LPPROC",
56 "LPWSTR",
57 "MSVCRT",
58 "NOARG",
59 "NOCOMPLETE",
60 "NOINHERIT",
61 "RENORMALIZE",
62 "STARTF",
63 "STARTUPINFOEXW",
64 "Schindelin",
65 "UCRT",
66 "YESNO",
67 "argcp",
68 "beginthreadex",
69 "committish",
70 "contentp",
71 "cpath",
72 "cpidx",
73 "ctim",
74 "dequote",
75 "envw",
76 "ewah",
77 "fdata",
78 "fherr",
79 "fhin",
80 "fhout",
81 "fragp",
82 "fsmonitor",
83 "hnsec",
84 "idents",
85 "includeif",
86 "interpr",
87 "iprog",
88 "isexe",
89 "iskeychar",
90 "kompare",
91 "mksnpath",
92 "mktag",
93 "mktree",
94 "mmblob",
95 "mmbuffer",
96 "mmfile",
97 "noenv",
98 "nparents",
99 "ntpath",
100 "ondisk",
101 "ooid",
102 "oplen",
103 "osdl",
104 "pnew",
105 "pold",
106 "ppinfo",
107 "pushf",
108 "pushv",
109 "rawsz",
110 "rebasing",
111 "reencode",
112 "repo",
113 "rerere",
114 "scld",
115 "sharedrepo",
116 "spawnv",
117 "spawnve",
118 "spawnvpe",
119 "strdup'ing",
120 "submodule",
121 "submodules",
122 "topath",
123 "topo",
124 "tpatch",
125 "unexecutable",
126 "unhide",
127 "unkc",
128 "unkv",
129 "unmark",
130 "unmatch",
131 "unsets",
132 "unshown",
133 "untracked",
134 "untrackedcache",
135 "unuse",
136 "upos",
137 "uval",
138 "vreportf",
139 "wargs",
140 "wargv",
141 "wbuffer",
142 "wcmd",
143 "wcsnicmp",
144 "wcstoutfdup",
145 "wdeltaenv",
146 "wdir",
147 "wenv",
148 "wenvblk",
149 "wenvcmp",
150 "wenviron",
151 "wenvpos",
152 "wenvsz",
153 "wfile",
154 "wfilename",
155 "wfopen",
156 "wfreopen",
157 "wfullpath",
158 "which'll",
159 "wlink",
160 "wmain",
161 "wmkdir",
162 "wmktemp",
163 "wnewpath",
164 "wotype",
165 "wpath",
166 "wpathname",
167 "wpgmptr",
168 "wpnew",
169 "wpointer",
170 "wpold",
171 "wpos",
172 "wputenv",
173 "wrmdir",
174 "wship",
175 "wtarget",
176 "wtemplate",
177 "wunlink",
178 "xcalloc",
179 "xgetcwd",
180 "xmallocz",
181 "xmemdupz",
182 "xmmap",
183 "xopts",
184 "xrealloc",
185 "xsnprintf",
186 "xutftowcs",
187 "xutftowcsn",
188 "xwcstoutf"
189 ],
190 "cSpell.ignoreRegExpList": [
191 "\\\"(DIRC|FSMN|REUC|UNTR)\\\"",
192 "\\\\u[0-9a-fA-Fx]{4}\\b",
193 "\\b(filfre|frotz|xyzzy)\\b",
194 "\\bCMIT_FMT_DEFAULT\\b",
195 "\\bde-munge\\b",
196 "\\bGET_OID_DISAMBIGUATORS\\b",
197 "\\bHASH_RENORMALIZE\\b",
198 "\\bTREESAMEness\\b",
199 "\\bUSE_STDEV\\b",
200 "\\Wchar *\\*\\W*utfs\\W",
201 "cURL's",
202 "nedmalloc'ed",
203 "ntifs\\.h",
204 ],
205}
206EOF
207die "Could not write settings.json"
208
209# Infer some setup-specific locations/names
210
211GCCPATH="$(which gcc)"
212GDBPATH="$(which gdb)"
213MAKECOMMAND="make -j5 DEVELOPER=1"
214OSNAME=
215X=
216case "$(uname -s)" in
217MINGW*)
218 GCCPATH="$(cygpath -am "$GCCPATH")"
219 GDBPATH="$(cygpath -am "$GDBPATH")"
220 MAKE_BASH="$(cygpath -am /git-cmd.exe) --command=usr\\\\bin\\\\bash.exe"
221 MAKECOMMAND="$MAKE_BASH -lc \\\"$MAKECOMMAND\\\""
222 OSNAME=Win32
223 X=.exe
224 ;;
225Linux)
226 OSNAME=Linux
227 ;;
228Darwin)
229 OSNAME=macOS
230 ;;
231esac
232
233# Default build task
234
235cat >.vscode/tasks.json.new <<EOF ||
236{
237 // See https://go.microsoft.com/fwlink/?LinkId=733558
238 // for the documentation about the tasks.json format
239 "version": "2.0.0",
240 "tasks": [
241 {
242 "label": "make",
243 "type": "shell",
244 "command": "$MAKECOMMAND",
245 "group": {
246 "kind": "build",
247 "isDefault": true
248 }
249 }
250 ]
251}
252EOF
253die "Could not install default build task"
254
255# Debugger settings
256
257cat >.vscode/launch.json.new <<EOF ||
258{
259 // Use IntelliSense to learn about possible attributes.
260 // Hover to view descriptions of existing attributes.
261 // For more information, visit:
262 // https://go.microsoft.com/fwlink/?linkid=830387
263 "version": "0.2.0",
264 "configurations": [
265 {
266 "name": "(gdb) Launch",
267 "type": "cppdbg",
268 "request": "launch",
269 "program": "\${workspaceFolder}/git$X",
270 "args": [],
271 "stopAtEntry": false,
272 "cwd": "\${workspaceFolder}",
273 "environment": [],
274 "externalConsole": true,
275 "MIMode": "gdb",
276 "miDebuggerPath": "$GDBPATH",
277 "setupCommands": [
278 {
279 "description": "Enable pretty-printing for gdb",
280 "text": "-enable-pretty-printing",
281 "ignoreFailures": true
282 }
283 ]
284 }
285 ]
286}
287EOF
288die "Could not write launch configuration"
289
290# C/C++ extension settings
291
292make -f - OSNAME=$OSNAME GCCPATH="$GCCPATH" vscode-init \
293 >.vscode/c_cpp_properties.json <<\EOF ||
294include Makefile
295
296vscode-init:
297 @mkdir -p .vscode && \
298 incs= && defs= && \
299 for e in $(ALL_CFLAGS) \
300 '-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \
301 '-DGIT_LOCALE_PATH="$(localedir_relative_SQ)"' \
302 '-DBINDIR="$(bindir_relative_SQ)"' \
303 '-DFALLBACK_RUNTIME_PREFIX="$(prefix_SQ)"' \
304 '-DDEFAULT_GIT_TEMPLATE_DIR="$(template_dir_SQ)"' \
305 '-DETC_GITCONFIG="$(ETC_GITCONFIG_SQ)"' \
306 '-DETC_GITATTRIBUTES="$(ETC_GITATTRIBUTES_SQ)"' \
307 '-DGIT_LOCALE_PATH="$(localedir_relative_SQ)"' \
308 '-DCURL_DISABLE_TYPECHECK', \
309 '-DGIT_HTML_PATH="$(htmldir_relative_SQ)"' \
310 '-DGIT_MAN_PATH="$(mandir_relative_SQ)"' \
311 '-DGIT_INFO_PATH="$(infodir_relative_SQ)"'; do \
312 case "$$e" in \
313 -I.) \
314 incs="$$(printf '% 16s"$${workspaceRoot}",\n%s' \
315 "" "$$incs")" \
316 ;; \
317 -I/*) \
318 incs="$$(printf '% 16s"%s",\n%s' \
319 "" "$${e#-I}" "$$incs")" \
320 ;; \
321 -I*) \
322 incs="$$(printf '% 16s"$${workspaceRoot}/%s",\n%s' \
323 "" "$${e#-I}" "$$incs")" \
324 ;; \
325 -D*) \
326 defs="$$(printf '% 16s"%s",\n%s' \
327 "" "$$(echo "$${e#-D}" | sed 's/"/\\&/g')" \
328 "$$defs")" \
329 ;; \
330 esac; \
331 done && \
332 echo '{' && \
333 echo ' "configurations": [' && \
334 echo ' {' && \
335 echo ' "name": "$(OSNAME)",' && \
336 echo ' "intelliSenseMode": "clang-x64",' && \
337 echo ' "includePath": [' && \
338 echo "$$incs" | sort | sed '$$s/,$$//' && \
339 echo ' ],' && \
340 echo ' "defines": [' && \
341 echo "$$defs" | sort | sed '$$s/,$$//' && \
342 echo ' ],' && \
343 echo ' "browse": {' && \
344 echo ' "limitSymbolsToIncludedHeaders": true,' && \
345 echo ' "databaseFilename": "",' && \
346 echo ' "path": [' && \
347 echo ' "$${workspaceRoot}"' && \
348 echo ' ]' && \
349 echo ' },' && \
350 echo ' "cStandard": "c11",' && \
351 echo ' "cppStandard": "c++17",' && \
352 echo ' "compilerPath": "$(GCCPATH)"' && \
353 echo ' }' && \
354 echo ' ],' && \
355 echo ' "version": 4' && \
356 echo '}'
357EOF
358die "Could not write settings for the C/C++ extension"
359
360for file in .vscode/settings.json .vscode/tasks.json .vscode/launch.json
361do
362 if test -f $file
363 then
364 if git diff --no-index --quiet --exit-code $file $file.new
365 then
366 rm $file.new
367 else
368 printf "The file $file.new has these changes:\n\n"
369 git --no-pager diff --no-index $file $file.new
370 printf "\n\nMaybe \`mv $file.new $file\`?\n\n"
371 fi
372 else
373 mv $file.new $file
374 fi
375done