diff --git a/icons/vscode/metals/book-dark.png b/icons/vscode/metals/book-dark.png new file mode 100644 index 0000000..599b98a Binary files /dev/null and b/icons/vscode/metals/book-dark.png differ diff --git a/icons/vscode/metals/book-light.png b/icons/vscode/metals/book-light.png new file mode 100644 index 0000000..5a1551d Binary files /dev/null and b/icons/vscode/metals/book-light.png differ diff --git a/icons/vscode/metals/bug-dark.png b/icons/vscode/metals/bug-dark.png new file mode 100644 index 0000000..70780cb Binary files /dev/null and b/icons/vscode/metals/bug-dark.png differ diff --git a/icons/vscode/metals/bug-light.png b/icons/vscode/metals/bug-light.png new file mode 100644 index 0000000..a7936a8 Binary files /dev/null and b/icons/vscode/metals/bug-light.png differ diff --git a/icons/vscode/metals/class.png b/icons/vscode/metals/class.png new file mode 100644 index 0000000..f580f38 Binary files /dev/null and b/icons/vscode/metals/class.png differ diff --git a/icons/vscode/metals/enum.png b/icons/vscode/metals/enum.png new file mode 100644 index 0000000..bf72c39 Binary files /dev/null and b/icons/vscode/metals/enum.png differ diff --git a/icons/vscode/metals/field.png b/icons/vscode/metals/field.png new file mode 100644 index 0000000..83e177f Binary files /dev/null and b/icons/vscode/metals/field.png differ diff --git a/icons/vscode/metals/github-dark.png b/icons/vscode/metals/github-dark.png new file mode 100644 index 0000000..1c2bbb0 Binary files /dev/null and b/icons/vscode/metals/github-dark.png differ diff --git a/icons/vscode/metals/github-light.png b/icons/vscode/metals/github-light.png new file mode 100644 index 0000000..d5c4fb6 Binary files /dev/null and b/icons/vscode/metals/github-light.png differ diff --git a/icons/vscode/metals/gitter-dark.png b/icons/vscode/metals/gitter-dark.png new file mode 100644 index 0000000..d38aaf7 Binary files /dev/null and b/icons/vscode/metals/gitter-dark.png differ diff --git a/icons/vscode/metals/gitter-light.png b/icons/vscode/metals/gitter-light.png new file mode 100644 index 0000000..f95ba24 Binary files /dev/null and b/icons/vscode/metals/gitter-light.png differ diff --git a/icons/vscode/metals/interface.png b/icons/vscode/metals/interface.png new file mode 100644 index 0000000..9e94a09 Binary files /dev/null and b/icons/vscode/metals/interface.png differ diff --git a/icons/vscode/metals/issue-opened-dark.png b/icons/vscode/metals/issue-opened-dark.png new file mode 100644 index 0000000..b5ed72b Binary files /dev/null and b/icons/vscode/metals/issue-opened-dark.png differ diff --git a/icons/vscode/metals/issue-opened-light.png b/icons/vscode/metals/issue-opened-light.png new file mode 100644 index 0000000..c812557 Binary files /dev/null and b/icons/vscode/metals/issue-opened-light.png differ diff --git a/icons/vscode/metals/method.png b/icons/vscode/metals/method.png new file mode 100644 index 0000000..131b890 Binary files /dev/null and b/icons/vscode/metals/method.png differ diff --git a/icons/vscode/metals/object.png b/icons/vscode/metals/object.png new file mode 100644 index 0000000..a958308 Binary files /dev/null and b/icons/vscode/metals/object.png differ diff --git a/icons/vscode/metals/trait.png b/icons/vscode/metals/trait.png new file mode 100644 index 0000000..aa8497a Binary files /dev/null and b/icons/vscode/metals/trait.png differ diff --git a/icons/vscode/metals/twitter-dark.png b/icons/vscode/metals/twitter-dark.png new file mode 100644 index 0000000..6f36803 Binary files /dev/null and b/icons/vscode/metals/twitter-dark.png differ diff --git a/icons/vscode/metals/twitter-light.png b/icons/vscode/metals/twitter-light.png new file mode 100644 index 0000000..d066165 Binary files /dev/null and b/icons/vscode/metals/twitter-light.png differ diff --git a/icons/vscode/metals/val.png b/icons/vscode/metals/val.png new file mode 100644 index 0000000..eaa14ea Binary files /dev/null and b/icons/vscode/metals/val.png differ diff --git a/icons/vscode/metals/var.png b/icons/vscode/metals/var.png new file mode 100644 index 0000000..933851a Binary files /dev/null and b/icons/vscode/metals/var.png differ diff --git a/lsp-treemacs-tvp.el b/lsp-treemacs-tvp.el new file mode 100644 index 0000000..ba55fe1 --- /dev/null +++ b/lsp-treemacs-tvp.el @@ -0,0 +1,182 @@ +;;; lsp-treemacs-tvp.el --- LSP Tree View Protocol -*- lexical-binding: t; -*- + +;; Copyright (C) 2019 Evgeny Kurnevsky + +;; Author: Evgeny Kurnevsky +;; 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 . + +;;; Commentary: + +;; Metals Tree View Protocol implementation + +;;; Code: +(require 'treemacs) +(require 'treemacs-extensions) +(require 'treemacs-icons) + +(require 'lsp-mode) + +(defgroup lsp-treemacs-tvp nil + "LSP Tree View Protocol." + :group 'lsp-treemacs + :link '(url-link "https://scalameta.org/metals/docs/editors/tree-view-protocol.html") + :package-version '(lsp-treemacs . "0.1")) + +(defcustom lsp-treemacs-tvp-theme 'Metals-light + "The theme for Tree View icons." + :group 'lsp-treemacs-tvp + :type '(choice + (const :tag "Light" 'Metals-light) + (const :tag "Dark" 'Metals-dark)) + :package-version '(lsp-treemacs . "0.1")) + +(treemacs-create-theme "Metals" + :icon-directory (f-join (f-dirname (or load-file-name buffer-file-name)) "icons/vscode/metals") + :config + (progn + (treemacs-create-icon :file "class.png" :extensions (class) :fallback "-") + (treemacs-create-icon :file "enum.png" :extensions (enum) :fallback "-") + (treemacs-create-icon :file "field.png" :extensions (field) :fallback "-") + (treemacs-create-icon :file "interface.png" :extensions (interface) :fallback "-") + (treemacs-create-icon :file "method.png" :extensions (method) :fallback "-") + (treemacs-create-icon :file "object.png" :extensions (object) :fallback "-") + (treemacs-create-icon :file "trait.png" :extensions (trait) :fallback "-") + (treemacs-create-icon :file "val.png" :extensions (val) :fallback "-") + (treemacs-create-icon :file "var.png" :extensions (var) :fallback "-"))) + +(treemacs-create-theme "Metals-dark" + :icon-directory (f-join (f-dirname (or load-file-name buffer-file-name)) "icons/vscode/metals") + :config + (progn + (treemacs-create-icon :file "book-dark.png" :extensions (book) :fallback "-") + (treemacs-create-icon :file "bug-dark.png" :extensions (bug) :fallback "-") + (treemacs-create-icon :file "github-dark.png" :extensions (github) :fallback "-") + (treemacs-create-icon :file "gitter-dark.png" :extensions (gitter) :fallback "-") + (treemacs-create-icon :file "issue-opened-dark.png" :extensions (issue-opened) :fallback "-") + (treemacs-create-icon :file "twitter-dark.png" :extensions (twitter) :fallback "-"))) + +(treemacs-create-theme "Metals-light" + :icon-directory (f-join (f-dirname (or load-file-name buffer-file-name)) "icons/vscode/metals") + :config + (progn + (treemacs-create-icon :file "book-light.png" :extensions (book) :fallback "-") + (treemacs-create-icon :file "bug-light.png" :extensions (bug) :fallback "-") + (treemacs-create-icon :file "github-light.png" :extensions (github) :fallback "-") + (treemacs-create-icon :file "gitter-light.png" :extensions (gitter) :fallback "-") + (treemacs-create-icon :file "issue-opened-light.png" :extensions (issue-opened) :fallback "-") + (treemacs-create-icon :file "twitter-light.png" :extensions (twitter) :fallback "-"))) + +(defun lsp-treemacs-workspace-at-point () + "Find the LSP workspace at the point in the treemacs buffer." + (lsp-find-workspace 'metals (treemacs-project->path (treemacs-project-at-point)))) + +(defun lsp-treemacs-tvp--children (viewId &optional nodeUri) + "Get children for NODEURI with VIEWID." + (with-lsp-workspace (lsp-treemacs-workspace-at-point) + (append (ht-get (lsp-request "metals/treeViewChildren" `(:viewId ,viewId + :nodeUri ,nodeUri)) "nodes") nil))) + +(defun lsp-treemacs-tvp--ret-action (&rest _) + "Tree View RET action." + (with-lsp-workspace (lsp-treemacs-workspace-at-point) + (let ((command (treemacs--prop-at-point :command))) + (pcase (ht-get command "command") + (`"metals-echo-command" (lsp-send-execute-command (elt (ht-get command "arguments") 0))) + (`"metals.goto" (lsp-send-execute-command "goto" (ht-get command "arguments"))) + (`"build-connect" (lsp-send-execute-command "build-connect")) + (`"build-import" (lsp-send-execute-command "build-import")) + (`"compile-cascade" (lsp-send-execute-command "compile-cascade")) + (`"compile-cancel" (lsp-send-execute-command "compile-cancel")) + (c (lsp-warn "Unknown metals Tree View command: %s" c)))))) + +(defun lsp-treemacs-tvp--icon (name &optional default) + "Get the icon for the NAME. +Return DEFAULT if there is no such icon." + (pcase name + (`"class" (treemacs-get-icon-value 'class nil 'Metals)) + (`"enum" (treemacs-get-icon-value 'enum nil 'Metals)) + (`"field" (treemacs-get-icon-value 'field nil 'Metals)) + (`"interface" (treemacs-get-icon-value 'interface nil 'Metals)) + (`"method" (treemacs-get-icon-value 'method nil 'Metals)) + (`"object" (treemacs-get-icon-value 'object nil 'Metals)) + (`"trait" (treemacs-get-icon-value 'trait nil 'Metals)) + (`"val" (treemacs-get-icon-value 'val nil 'Metals)) + (`"var" (treemacs-get-icon-value 'var nil 'Metals)) + (`"book" (treemacs-get-icon-value 'book nil lsp-treemacs-tvp-theme)) + (`"bug" (treemacs-get-icon-value 'bug nil lsp-treemacs-tvp-theme)) + (`"github" (treemacs-get-icon-value 'github nil lsp-treemacs-tvp-theme)) + (`"gitter" (treemacs-get-icon-value 'gitter nil lsp-treemacs-tvp-theme)) + (`"issue-opened" (treemacs-get-icon-value 'issue-opened nil lsp-treemacs-tvp-theme)) + (`"twitter" (treemacs-get-icon-value 'twitter nil lsp-treemacs-tvp-theme)) + (_ default))) + +(treemacs-define-leaf-node tvp-leaf 'dynamic-icon + :ret-action #'lsp-treemacs-tvp--ret-action) + +(treemacs-define-expandable-node tvp-node + :icon-open-form (lsp-treemacs-tvp--icon (treemacs-button-get node :icon) (treemacs-as-icon " ▾ ")) + :icon-closed-form (lsp-treemacs-tvp--icon (treemacs-button-get node :icon) (treemacs-as-icon " ▸ ")) + :ret-action #'lsp-treemacs-tvp--ret-action + :query-function (lsp-treemacs-tvp--children (treemacs-button-get node :viewId) (treemacs-button-get node :nodeUri)) + :render-action (treemacs-render-node + :icon (lsp-treemacs-tvp--icon (ht-get item "icon") (if (ht-get item "collapseState") + (treemacs-as-icon " ▸ ") + (treemacs-as-icon " • "))) + :label-form (ht-get item "label") + :state (if (ht-get item "collapseState") + treemacs-tvp-node-closed-state + treemacs-tvp-leaf-state) + :face 'default + :key-form (ht-get item "nodeUri") + :more-properties (:viewId (ht-get item "viewId") + :nodeUri (ht-get item "nodeUri") + :command (ht-get item "command") + :icon (ht-get item "icon")))) + +(treemacs-define-expandable-node tvp-root + :icon-open (treemacs-as-icon " ▾ ") + :icon-closed (treemacs-as-icon " ▸ ") + :query-function `(,(ht ("label" "Build") ("viewId" "metalsBuild")) + ,(ht ("label" "Compile") ("viewId" "metalsCompile")) + ,(ht ("label" "Help") ("viewId" "metalsHelp"))) + :render-action (treemacs-render-node + :icon (treemacs-as-icon " ▸ ") + :label-form (ht-get item "label") + :state treemacs-tvp-node-closed-state + :face 'default + :key-form (ht-get item "label") + :more-properties (:viewId (ht-get item "viewId") + :nodeUri (ht-get item "nodeUri"))) + :root-marker t + :root-label "Tree View" + :root-face 'default + :root-key-form 'TreeView) + +(defun lsp-treemacs-tvp--predicate (project) + "Check if the Metals Tree View should be displayed for the PROJECT." + (lsp-find-workspace 'metals (treemacs-project->path project))) + +(treemacs-define-project-extension + :extension #'treemacs-TVP-ROOT-extension + :predicate #'lsp-treemacs-tvp--predicate + :position 'top) + +(provide 'lsp-treemacs-tvp) +;;; lsp-treemacs-tvp.el ends here + +;; Local Variables: +;; flycheck-disabled-checkers: (emacs-lisp-checkdoc) +;; End: diff --git a/lsp-treemacs.el b/lsp-treemacs.el index 6aa17f2..e2ddae4 100644 --- a/lsp-treemacs.el +++ b/lsp-treemacs.el @@ -33,6 +33,7 @@ (require 'treemacs-icons) (require 'lsp-mode) +(require 'lsp-treemacs-tvp) (defconst lsp-treemacs-deps-buffer-name "*Java Dependency List*")