;;; treemacs.el --- A tree style file viewer package -*- lexical-binding: t -*- ;; Copyright (C) 2021 Alexander Miller ;; 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: ;; Definition for the Helpful Hydras. ;; NOTE: This module is lazy-loaded. ;;; Code: (require 'cl-lib) (require 'dash) (require 'treemacs-logging) (require 'treemacs-scope) (require 'treemacs-interface) (require 'treemacs-bookmarks) (eval-when-compile (require 'treemacs-macros)) (treemacs-import-functions-from "treemacs" treemacs-edit-workspaces treemacs-version) (treemacs-import-functions-from "treemacs-hydras" treemacs--common-helpful-hydra/body treemacs--advanced-helpful-hydra/body) (cl-defun treemacs--find-keybind (func &optional (pad 8)) "Find the keybind for FUNC in treemacs. Return of cons of the key formatted for inclusion in the hydra string, including a minimum PAD width for alignment, and the key itself for the hydra heads. Prefer evil keybinds, otherwise pick the first result." (-if-let (keys (where-is-internal func)) (let ((key (key-description (-if-let (evil-keys (--first (eq 'treemacs-state (aref it 0)) keys)) (--map (aref evil-keys it) (number-sequence 1 (- (length evil-keys) 1))) (--map (aref (car keys) it) (number-sequence 0 (- (length (car keys)) 1))))))) (setf key (s-replace-all '(("" . "RET") ("" . "LEFT") ("" . "RIGHT") ("" . "UP") ("" . "DOWN") ("^" . "C-") ("⇢⌥" . ">O-") ("⌥" . "O-") ("⇢⌘" . ">#-") ("⌘" . "#-") ("⇧" . "S-")) key)) (cons (s-pad-right pad " " (format "_%s_:" key)) key)) (cons (s-pad-right pad " " (format "_%s_:" " ")) " "))) ;;;###autoload (defun treemacs-common-helpful-hydra () "Summon a helpful hydra to show you the treemacs keymap. This hydra will show the most commonly used keybinds for treemacs. For the more advanced (probably rarely used keybinds) see `treemacs-advanced-helpful-hydra'. The keybinds shown in this hydra are not static, but reflect the actual keybindings currently in use (including evil mode). If the hydra is unable to find the key a command is bound to it will show a blank instead." (interactive) (-if-let (b (treemacs-get-local-buffer)) (with-current-buffer b (let* ((title (format (propertize "Treemacs %s Common Helpful Hydra" 'face 'treemacs-help-title-face) (treemacs-version))) (adv-hint (format "%s %s" (propertize "For advanced keybinds see" 'face 'treemacs-help-title-face) (propertize "treemacs-advanced-helpful-hydra" 'face 'font-lock-function-name-face))) (column-nav (propertize "Navigation" 'face 'treemacs-help-column-face)) (column-nodes (propertize "Opening Nodes" 'face 'treemacs-help-column-face)) (column-toggles (propertize "Toggles " 'face 'treemacs-help-column-face)) (column-projects (propertize "Projects" 'face 'treemacs-help-column-face)) (key-adv-hydra (treemacs--find-keybind #'treemacs-advanced-helpful-hydra)) (key-root-up (treemacs--find-keybind #'treemacs-root-up)) (key-root-down (treemacs--find-keybind #'treemacs-root-down)) (key-next-line (treemacs--find-keybind #'treemacs-next-line)) (key-prev-line (treemacs--find-keybind #'treemacs-previous-line)) (key-next-neighbour (treemacs--find-keybind #'treemacs-next-neighbour)) (key-prev-neighbour (treemacs--find-keybind #'treemacs-previous-neighbour)) (key-goto-parent (treemacs--find-keybind #'treemacs-goto-parent-node)) (key-down-next-w (treemacs--find-keybind #'treemacs-next-line-other-window)) (key-up-next-w (treemacs--find-keybind #'treemacs-previous-line-other-window)) (key-ret (treemacs--find-keybind #'treemacs-RET-action)) (key-tab (treemacs--find-keybind #'treemacs-TAB-action)) (key-open (treemacs--find-keybind #'treemacs-visit-node-no-split)) (key-open-horiz (treemacs--find-keybind #'treemacs-visit-node-horizontal-split)) (key-open-vert (treemacs--find-keybind #'treemacs-visit-node-vertical-split)) (key-open-ace (treemacs--find-keybind #'treemacs-visit-node-ace)) (key-open-ace-h (treemacs--find-keybind #'treemacs-visit-node-ace-horizontal-split)) (key-open-ace-v (treemacs--find-keybind #'treemacs-visit-node-ace-vertical-split)) (key-open-ext (treemacs--find-keybind #'treemacs-visit-node-in-external-application)) (key-open-mru (treemacs--find-keybind #'treemacs-visit-node-in-most-recently-used-window)) (key-close-above (treemacs--find-keybind #'treemacs-collapse-parent-node)) (key-follow-mode (treemacs--find-keybind #'treemacs-follow-mode)) (key-fringe-mode (treemacs--find-keybind #'treemacs-fringe-indicator-mode)) (key-fwatch-mode (treemacs--find-keybind #'treemacs-filewatch-mode)) (key-git-mode (treemacs--find-keybind #'treemacs-git-mode)) (key-show-dotfiles (treemacs--find-keybind #'treemacs-toggle-show-dotfiles)) (key-toggle-width (treemacs--find-keybind #'treemacs-toggle-fixed-width)) (key-add-project (treemacs--find-keybind #'treemacs-add-project-to-workspace 12)) (key-remove-project (treemacs--find-keybind #'treemacs-remove-project-from-workspace 12)) (key-rename-project (treemacs--find-keybind #'treemacs-rename-project 12)) (hydra-str (format " %s %s (%s) %s ^^^^^^^^│ %s ^^^^^^^^^^^│ %s ^^^^^^│ %s ――――――――――――――――――――――――┼――――――――――――――――――――――――――――┼―――――――――――――――――――――――――┼―――――――――――――――――――――――――― %s next Line ^^^^│ %s dwim TAB ^^^^│ %s follow mode ^^^^│ %s add project %s prev line ^^^^│ %s dwim RET ^^^^│ %s filewatch mode ^^^^│ %s remove project %s next neighbour ^^^^│ %s open no split ^^^^│ %s git mode ^^^^│ %s rename project %s prev neighbour ^^^^│ %s open horizontal ^^^^│ %s show dotfiles ^^^^│ %s goto parent ^^^^│ %s open vertical ^^^^│ %s resizability ^^^^│ %s down next window ^^^^│ %s open ace ^^^^│ %s fringe indicator ^^^^│ %s up next window ^^^^│ %s open ace horizontal ^^^^│ │ %s root up ^^^^│ %s open ace vertical ^^^^│ │ %s root down ^^^^│ %s open mru window ^^^^│ │ │ %s open externally ^^^^│ │ │ %s close parent ^^^^│ │ " title adv-hint (car (s-split":" (car key-adv-hydra))) column-nav column-nodes column-toggles column-projects (car key-next-line) (car key-tab) (car key-follow-mode) (car key-add-project) (car key-prev-line) (car key-ret) (car key-fwatch-mode) (car key-remove-project) (car key-next-neighbour) (car key-open) (car key-git-mode) (car key-rename-project) (car key-prev-neighbour) (car key-open-horiz) (car key-show-dotfiles) (car key-goto-parent) (car key-open-vert) (car key-toggle-width) (car key-down-next-w) (car key-open-ace) (car key-fringe-mode) (car key-up-next-w) (car key-open-ace-h) (car key-root-up) (car key-open-ace-v) (car key-root-down) (car key-open-mru) (car key-open-ext) (car key-close-above)))) (eval `(defhydra treemacs--common-helpful-hydra (:exit nil :hint nil :columns 4) ,hydra-str (,(cdr key-adv-hydra) #'treemacs-advanced-helpful-hydra :exit t) (,(cdr key-next-line) #'treemacs-next-line) (,(cdr key-prev-line) #'treemacs-previous-line) (,(cdr key-root-up) #'treemacs-root-up) (,(cdr key-root-down) #'treemacs-root-down) (,(cdr key-down-next-w) #'treemacs-next-line-other-window) (,(cdr key-up-next-w) #'treemacs-previous-line-other-window) (,(cdr key-next-neighbour) #'treemacs-next-neighbour) (,(cdr key-prev-neighbour) #'treemacs-previous-neighbour) (,(cdr key-goto-parent) #'treemacs-goto-parent-node) (,(cdr key-ret) #'treemacs-RET-action) (,(cdr key-tab) #'treemacs-TAB-action) (,(cdr key-open) #'treemacs-visit-node-no-split) (,(cdr key-open-horiz) #'treemacs-visit-node-horizontal-split) (,(cdr key-open-vert) #'treemacs-visit-node-vertical-split) (,(cdr key-open-ace) #'treemacs-visit-node-ace) (,(cdr key-open-ace-h) #'treemacs-visit-node-ace-horizontal-split) (,(cdr key-open-ace-v) #'treemacs-visit-node-ace-vertical-split) (,(cdr key-open-mru) #'treemacs-visit-node-in-most-recently-used-window) (,(cdr key-open-ext) #'treemacs-visit-node-in-external-application) (,(cdr key-close-above) #'treemacs-collapse-parent-node) (,(cdr key-follow-mode) #'treemacs-follow-mode) (,(cdr key-show-dotfiles) #'treemacs-toggle-show-dotfiles) (,(cdr key-toggle-width) #'treemacs-toggle-fixed-width) (,(cdr key-fringe-mode) #'treemacs-fringe-indicator-mode) (,(cdr key-git-mode) #'treemacs-git-mode) (,(cdr key-fwatch-mode) #'treemacs-filewatch-mode) (,(cdr key-add-project) #'treemacs-add-project-to-workspace) (,(cdr key-remove-project) #'treemacs-remove-project-from-workspace) (,(cdr key-rename-project) #'treemacs-rename-project) ("ESC" nil "Exit")))) (treemacs--common-helpful-hydra/body)) (treemacs-log-failure "The helpful hydra cannot be summoned without an existing treemacs buffer."))) (defalias 'treemacs-helpful-hydra #'treemacs-common-helpful-hydra) ;;;###autoload (defun treemacs-advanced-helpful-hydra () "Summon a helpful hydra to show you the treemacs keymap. This hydra will show the more advanced (rarely used) keybinds for treemacs. For the more commonly used keybinds see `treemacs-common-helpful-hydra'. The keybinds shown in this hydra are not static, but reflect the actual keybindings currently in use (including evil mode). If the hydra is unable to find the key a command is bound to it will show a blank instead." (interactive) (-if-let (b (treemacs-get-local-buffer)) (with-current-buffer b (let* ((title (format (propertize "Treemacs %s Advanced Helpful Hydra" 'face 'treemacs-help-title-face) (treemacs-version))) (column-files (propertize "File Management" 'face 'treemacs-help-column-face)) (column-ws (propertize "Workspaces" 'face 'treemacs-help-column-face)) (column-misc (propertize "Misc." 'face 'treemacs-help-column-face)) (common-hint (format "%s %s" (propertize "For common keybinds see" 'face 'treemacs-help-title-face) (propertize "treemacs-common-helpful-hydra" 'face 'font-lock-function-name-face))) (key-common-hydra (treemacs--find-keybind #'treemacs-common-helpful-hydra)) (key-create-file (treemacs--find-keybind #'treemacs-create-file)) (key-create-dir (treemacs--find-keybind #'treemacs-create-dir)) (key-rename (treemacs--find-keybind #'treemacs-rename)) (key-delete (treemacs--find-keybind #'treemacs-delete)) (key-copy-file (treemacs--find-keybind #'treemacs-copy-file)) (key-move-file (treemacs--find-keybind #'treemacs-move-file)) (key-refresh (treemacs--find-keybind #'treemacs-refresh)) (key-set-width (treemacs--find-keybind #'treemacs-set-width)) (key-copy-path-abs (treemacs--find-keybind #'treemacs-copy-absolute-path-at-point)) (key-copy-path-rel (treemacs--find-keybind #'treemacs-copy-relative-path-at-point)) (key-copy-root (treemacs--find-keybind #'treemacs-copy-project-path-at-point)) (key-resort (treemacs--find-keybind #'treemacs-resort)) (key-bookmark (treemacs--find-keybind #'treemacs-add-bookmark)) (key-edit-ws (treemacs--find-keybind #'treemacs-edit-workspaces 12)) (key-create-ws (treemacs--find-keybind #'treemacs-create-workspace 12)) (key-remove-ws (treemacs--find-keybind #'treemacs-remove-workspace 12)) (key-rename-ws (treemacs--find-keybind #'treemacs-rename-workspace 12)) (key-switch-ws (treemacs--find-keybind #'treemacs-switch-workspace 12)) (key-fallback-ws (treemacs--find-keybind #'treemacs-set-fallback-workspace 12)) (hydra-str (format " %s %s (%s) %s ^^^^^^^^^^^^^│ %s ^^^^^^^^│ %s ――――――――――――――――――――┼―――――――――――――――――――――――――――――┼――――――――――――――――――――― %s create file ^^^^│ %s Edit Workspaces ^^^^^^^^│ %s refresh %s create dir ^^^^│ %s Create Workspace ^^^^^^^^│ %s (re)set width %s rename ^^^^│ %s Remove Workspace ^^^^^^^^│ %s copy path absolute %s delete ^^^^│ %s Rename Workspace ^^^^^^^^│ %s copy path relative %s copy ^^^^│ %s Switch Workspace ^^^^^^^^│ %s copy root path %s move ^^^^│ %s Set Fallback ^^^^^^^^│ %s re-sort │ │ %s bookmark " title common-hint (car (s-split":" (car key-common-hydra))) column-files column-ws column-misc (car key-create-file) (car key-edit-ws) (car key-refresh) (car key-create-dir) (car key-create-ws) (car key-set-width) (car key-rename) (car key-remove-ws) (car key-copy-path-abs) (car key-delete) (car key-rename-ws) (car key-copy-path-rel) (car key-copy-file) (car key-switch-ws) (car key-copy-root) (car key-move-file) (car key-fallback-ws) (car key-resort) (car key-bookmark)))) (eval `(defhydra treemacs--advanced-helpful-hydra (:exit nil :hint nil :columns 3) ,hydra-str (,(cdr key-common-hydra) #'treemacs-common-helpful-hydra :exit t) (,(cdr key-create-file) #'treemacs-create-file) (,(cdr key-create-dir) #'treemacs-create-dir) (,(cdr key-rename) #'treemacs-rename) (,(cdr key-delete) #'treemacs-delete) (,(cdr key-copy-file) #'treemacs-copy-file) (,(cdr key-move-file) #'treemacs-move-file) (,(cdr key-refresh) #'treemacs-refresh) (,(cdr key-set-width) #'treemacs-set-width) (,(cdr key-copy-path-rel) #'treemacs-copy-absolute-path-at-point) (,(cdr key-copy-path-abs) #'treemacs-copy-relative-path-at-point) (,(cdr key-copy-root) #'treemacs-copy-project-path-at-point) (,(cdr key-resort) #'treemacs-resort) (,(cdr key-bookmark) #'treemacs-add-bookmark) (,(cdr key-edit-ws) #'treemacs-edit-workspaces) (,(cdr key-create-ws) #'treemacs-create-workspace) (,(cdr key-remove-ws) #'treemacs-remove-workspace) (,(cdr key-rename-ws) #'treemacs-rename-workspace) (,(cdr key-switch-ws) #'treemacs-switch-workspace) (,(cdr key-fallback-ws) #'treemacs-set-fallback-workspace) ("ESC" nil "Exit")))) (treemacs--advanced-helpful-hydra/body)) (treemacs-log-failure "The helpful hydra cannot be summoned without an existing treemacs buffer."))) (provide 'treemacs-hydras) ;;; treemacs-hydras.el ends here