diff --git a/init.el b/init.el index c575292..1be8553 100644 --- a/init.el +++ b/init.el @@ -1528,7 +1528,6 @@ With PROJECT, give diagnostics for all buffers in the current project." ;; project.el (use-package project :bind (([remap project-compile] . my/project-compile-or-default) - ("C-c v" . my/project-eshell-or-default) :map project-prefix-map ("s" . my/project-eshell) ("u" . my/project-run)) @@ -1555,12 +1554,10 @@ With PROJECT, give diagnostics for all buffers in the current project." (call-interactively 'compile))) (defvar my/project-run-command nil "Command to run with `my/project-run'.") - (put 'my/project-run-command 'safe-local-variable (lambda (val) - (stringp val))) + (put 'my/project-run-command 'safe-local-variable #'stringp) (defvar my/project-run-dir nil "Directory to run project in with `my/project-run'.") - (put 'my/project-run-dir 'safe-local-variable (lambda (val) - (stringp val))) + (put 'my/project-run-dir 'safe-local-variable #'stringp) (defvar my/-project-run-history '() "Commands previously run with `my/project-run'") (defvar my/project-root-marker ".project-root" @@ -2404,6 +2401,25 @@ argument." ;; gnuplot (mostly for org-plot) (use-package gnuplot) +(defun my/dir-container-p (&optional dir) + "Return non-nil if DIR is a remote directory that is a container." + (member (file-remote-p default-directory 'method) + '("docker" "podman"))) +(defun my/dir-distrobox-p (&optional dir) + "Return non-nil if DIR is a remote directory that is a distrobox container." + (and (my/dir-container-p dir) + (let ((default-directory (or dir default-directory))) + (executable-find "distrobox-host-exec" t)))) +(defun my/dir-sudo-p (&optional dir) + "Return non-nil if DIR is a remote directory that is sudo, doas, etc.." + (member (file-remote-p (or dir default-directory) 'method) + '("sudo" "doas" "su" "sudoedit"))) +(defun my/dir-really-remote-p (&optional dir) + "Return non-nil if DIR is a remote directory that is really remote." + (and (file-remote-p (or dir default-directory)) + (not (my/dir-distrobox-p dir)) + (not (my/dir-sudo-p dir)))) + ;; eat (use-package eat :bind (("C-c V" . my/project-eat-or-default) @@ -2441,41 +2457,27 @@ argument." (add-hook 'eat--char-mode-hook #'my/-eat-disable-evil-in-char-mode) ;; Evil fixes done - (defvar my/project-eat-hash-table (make-hash-table :test 'equal) - "Hash table that maps project root dirs to eat buffers.") + (defun my/-eat-choose-good-term () + (if (my/dir-really-remote-p) + "xterm-256color" + (eat-term-get-suitable-term-name))) + (setq eat-term-name #'my/-eat-choose-good-term) (defun my/-eat-shell-for-cwd () "Return a good shell for CWD, or nil if the default shell should be used." - (when (file-remote-p default-directory) + (when (my/dir-really-remote-p) "/bin/sh")) - (defun my/project-eat (prompt &optional arg) + (defun my/project-eat (&optional arg prompt) "Switch to or create a eat buffer in the current projects root." - (interactive (list t current-prefix-arg)) + (interactive (list current-prefix-arg t)) (if-let ((proj (project-current prompt)) (default-directory (project-root proj))) - (if-let ((eat-buff (gethash default-directory - my/project-eat-hash-table)) - ((buffer-live-p eat-buff))) - (switch-to-buffer eat-buff) - (let ((eat-buffer-name (concat "*eat for project " default-directory - "*")) - (eat-term-name (if (file-remote-p default-directory) - "xterm-256color" - eat-term-name))) - (puthash default-directory - (eat (my/-eat-shell-for-cwd) arg) - my/project-eat-hash-table))))) + (let ((eat-buffer-name (format "*eat for project %s*" default-directory))) + (eat (my/-eat-shell-for-cwd) arg)))) (defun my/project-eat-or-default (&optional arg) "Open an eat for the current project, otherwise, open a normal eat." (interactive "P") - (unless (my/project-eat nil) - (if-let ((eat-buff (gethash nil my/project-eat-hash-table)) - ((buffer-live-p eat-buff))) - (switch-to-buffer eat-buff) - (puthash nil (let ((eat-term-name (if (file-remote-p default-directory) - "xterm-256color" - eat-term-name))) - (eat (my/-eat-shell-for-cwd) arg)) - my/project-eat-hash-table))))) + (unless (my/project-eat arg) + (eat (my/-eat-shell-for-cwd) arg)))) ;; eshell stuff (use-package eshell @@ -2500,21 +2502,6 @@ argument." (cl-second elt)))) eshell-command-aliases-list)) - (defun my/-eshell-container-p (&optional dir) - (member (file-remote-p default-directory 'method) - '("docker" "podman"))) - (defun my/-eshell-distrobox-p (&optional dir) - (and (my/-eshell-container-p dir) - (let ((default-directory (or dir default-directory))) - (executable-find "distrobox-host-exec" t)))) - (defun my/-eshell-sudo-p (&optional dir) - (member (file-remote-p (or dir default-directory) 'method) - '("sudo" "doas" "su" "sudoedit"))) - (defun my/-eshell-really-remote-p (&optional dir) - (and (file-remote-p (or dir default-directory)) - (not (my/-eshell-distrobox-p dir)) - (not (my/-eshell-sudo-p dir)))) - (defun eshell/-captive-cd (&optional dir &rest _) (cond ((not dir) @@ -2532,7 +2519,7 @@ argument." (when (or force (not (equal my/-eshell-last-remote-system (file-remote-p default-directory)))) (kill-local-variable 'eshell-syntax-highlighting-highlight-in-remote-dirs) - (if (my/-eshell-really-remote-p) + (if (my/dir-really-remote-p) (setq-local eshell-command-aliases-list (my/-eshell-filter-alias-list)) (setq-local eshell-command-aliases-list (default-toplevel-value 'eshell-command-aliases-list))) @@ -2540,12 +2527,12 @@ argument." (copy-tree eshell-command-aliases-list)) (when (file-remote-p default-directory) (add-to-list 'eshell-command-aliases-list '("cd" "-captive-cd $1") t)) - (when (or (my/-eshell-distrobox-p) - (my/-eshell-sudo-p)) + (when (or (my/dir-distrobox-p) + (my/dir-sudo-p)) (setq-local eshell-syntax-highlighting-highlight-in-remote-dirs t) (setf (alist-get "pwd" eshell-command-aliases-list nil nil 'equal) '("(directory-file-name (file-remote-p default-directory 'localname))"))) - (when (my/-eshell-distrobox-p) + (when (my/dir-distrobox-p) (unless (executable-find "eza" t) (if (executable-find "exa" t) (setf (alist-get "ls" eshell-command-aliases-list nil nil 'equal) @@ -2603,7 +2590,7 @@ If no name is given, list all bookmarks instead." (after-path (match-string 2 name)) (bm-path (bookmark-get-filename bm-name)) (full-path (expand-file-name after-path bm-path))) - (when (my/-eshell-distrobox-p) + (when (my/dir-distrobox-p) (setq full-path (concat (file-remote-p default-directory) full-path))) (if (not (file-directory-p full-path)) @@ -2671,15 +2658,16 @@ If no name is given, list all bookmarks instead." (set-face-attribute 'eshell-starship-icon-face nil :family "FiraCode Nerd Font")) -(defun my/open-eshell-unless-remote (&optional arg) - "Open either an Eshell or eat terminal based on `default-directory'. -If `default-directory' is remote, call `my/project-eat-or-default'. Otherwise, -call `my/project-eshell-or-default'. ARG is the same as for either of the above -functions (only eshell uses it at the time of writing)." +(defvar my/eshell-or-eat-hook nil + "Hook to determine weather `my/open-shell-dwin' uses `eshell' or `eat'.") +(defun my/open-shell-dwim (&optional arg) + "Open either an `eshell' or `eat' terminal based on `my/eshell-or-eat-hook'. +ARG is the same as for either of the above functions." (interactive "P") - (if (my/-eshell-really-remote-p) + (if (run-hook-with-args-until-success 'my/eshell-or-eat-hook) (my/project-eat-or-default arg) (my/project-eshell-or-default arg))) +(keymap-global-set "C-c v" #'my/open-shell-dwim) ;; proced (use-package proced