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 122
|
;;; dap-launch.el --- support launch.json -*- lexical-binding: t -*-
;; Copyright (C) 2020 Nikita Bloshchanevich
;; Author: Nikita Bloshchanevich <nikblos@outlook.com>
;; Keywords: languages
;; 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:
;; Extend dap-mode with support for launch.json files
;;; Code:
(require 'lsp-mode)
(require 'json)
(declare-function dap-variables-find-vscode-config "dap-variables" (f root))
(defun dap-launch-find-launch-json ()
"Return the path to current project's launch.json file.
Yields nil if it cannot be found or there is no project."
(when-let ((root (lsp-workspace-root)))
(require 'dap-variables)
(dap-variables-find-vscode-config "launch.json" root)))
(defun dap-launch-get-launch-json ()
"Parse the project's launch.json as json data and return the result."
(require 'dap-utils)
(when-let ((launch-json (dap-launch-find-launch-json))
(json-object-type 'plist)
;; Use 'vector instead of 'list. With 'list for array type,
;; json-encode-list interpreted a list with one plist element as
;; an alist. Using 'list, it turned the following value of
;; pathMappings:
;;
;; "pathMappings": [
;; {
;; "localRoot": "${workspaceFolder}",
;; "remoteRoot": "."
;; }
;; ]
;;
;; into:
;;
;; ((:localRoot "${workspaceFolder}" :remoteRoot "."))
;;
;; and then into:
;;
;; "pathMappings": {
;; "localRoot": [
;; "${workspaceFolder}",
;; "remoteRoot",
;; "."
;; ]
;; }
(json-array-type 'vector))
(with-temp-buffer
;; NOTE: insert-file-contents does not move point
(insert-file-contents launch-json)
(dap-utils-sanitize-json)
;; dap-launch-remove-comments does move point
(goto-char (point-min))
(json-read))))
(defun dap-launch-configuration-get-name (conf)
"Return the name of launch configuration CONF."
(plist-get conf :name))
(defun dap-launch-configuration-prepend-name (conf)
"Prepend the name of CONF to it as a string.
Extract the name from the :name property."
(push (dap-launch-configuration-get-name conf) conf))
(defun dap--launch-extract-environment (conf)
"Transform environment config into dap-mode format.
This handles a single configuration plist."
(if (not (plist-get conf :environment))
;; No environment specified, just return the old configuration
conf
;; Standard format for the "environment" key is
;; {"name": "foo", "value": "bar"},
;; which results in a (:name "foo" :value "bar) plist.
;; We need to transform this into a ("foo" . "bar") cons cell.
(let ((environ-spec (mapcar
(lambda (env-plist)
(cons (plist-get env-plist :name)
(plist-get env-plist :value)))
(plist-get conf :environment))))
(plist-put conf :environment-variables environ-spec))))
(defun dap--launch-extract-environments (conflist)
"Transform environment config into dap-mode format.
This is intended to be run on a list of configurations."
(mapcar #'dap--launch-extract-environment conflist))
(defun dap-launch-parse-launch-json (json)
"Return a list of all launch configurations in JSON.
JSON must have been acquired with `dap-launch--get-launch-json'."
(mapcar #'dap-launch-configuration-prepend-name
(dap--launch-extract-environments
(or (plist-get json :configurations) (list json)))))
(defun dap-launch-find-parse-launch-json ()
"Return a list of all launch configurations for the current project.
Usable as a dap-launch-configuration-providers backend."
(when-let ((launch-json (dap-launch-get-launch-json)))
(dap-launch-parse-launch-json launch-json)))
(provide 'dap-launch)
;;; dap-launch.el ends here
|