branch: externals/dtache commit 6c51554e6929086af7f9b9007b2bbbe1e9f3a256 Author: Niklas Eklund <niklas.ekl...@posteo.net> Commit: Niklas Eklund <niklas.ekl...@posteo.net>
Improve package configuration --- dtache-compile.el | 1 + dtache-dired.el | 45 ++++++++++++++++++++++++ dtache-eshell.el | 29 ++++++++------- dtache-extra.el | 53 ++++++++++++++++++++++++++++ dtache-init.el | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ dtache-org.el | 1 + dtache-shell.el | 2 ++ dtache-vterm.el | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++ dtache.el | 1 + 9 files changed, 317 insertions(+), 15 deletions(-) diff --git a/dtache-compile.el b/dtache-compile.el index 6ed9f3060e..3d3bc2be5f 100644 --- a/dtache-compile.el +++ b/dtache-compile.el @@ -90,6 +90,7 @@ Optionally EDIT-COMMAND." (dtache-compile-attach session) (dtache-compile-session session)))) +;;;###autoload (defun dtache-compile-start (_) "Run in `compilation-start-hook' if `dtache-enabled'." (when dtache-enabled diff --git a/dtache-dired.el b/dtache-dired.el new file mode 100644 index 0000000000..098692d918 --- /dev/null +++ b/dtache-dired.el @@ -0,0 +1,45 @@ +;;; dtache-dired.el --- Dtache integration for dired -*- lexical-binding: t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; 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 <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package integrates `dtache' with `dired'. + +;;; Code: + +;;;; Requirements + +(require 'dired) +(require 'dtache) + +;;;; Functions + +;;;###autoload +(defun dtache-dired-do-shell-command (dired-do-shell-command &rest args) + "Ensure `dtache' is used before running DIRED-DO-SHELL-COMMAND with ARGS." + (cl-letf* ((dtache-session-origin 'dired) + ((symbol-function #'dired-run-shell-command) + (lambda (command) + (dtache-start-session command) + nil))) + (apply dired-do-shell-command args))) + +(provide 'dtache-dired) + +;;; dtache-dired.el ends here diff --git a/dtache-eshell.el b/dtache-eshell.el index f6756ee3b1..9cb5e5cc26 100644 --- a/dtache-eshell.el +++ b/dtache-eshell.el @@ -71,6 +71,7 @@ If prefix-argument directly DETACH from the session." (dtache-session-mode (if detach 'create 'create-and-attach)) (dtache-enabled t) (dtache--current-session nil)) + (advice-add #'eshell-external-command :around #'dtache-eshell-external-command) (call-interactively #'eshell-send-input))) ;;;###autoload @@ -99,20 +100,20 @@ If prefix-argument directly DETACH from the session." ;;;; Support functions -(defun dtache-eshell--external-command (orig-fun &rest args) +;;;###autoload +(defun dtache-eshell-external-command (orig-fun &rest args) "Advice `eshell-external-command' to optionally use `dtache'." - (if dtache-enabled - (let* ((dtache-session-action dtache-eshell-session-action) - (command (string-trim-right - (mapconcat #'identity - (flatten-list args) - " "))) - (session (dtache-create-session command)) - (command (dtache-dtach-command session))) - (setq dtache--buffer-session session) - (setq dtache-enabled nil) - (apply orig-fun `(,(seq-first command) ,(seq-rest command)))) - (apply orig-fun args))) + (let* ((dtache-session-action dtache-eshell-session-action) + (command (string-trim-right + (mapconcat #'identity + (flatten-list args) + " "))) + (session (dtache-create-session command)) + (command (dtache-dtach-command session))) + (advice-remove #'eshell-external-command #'dtache-eshell-external-command) + (setq dtache--buffer-session session) + (setq dtache-enabled nil) + (apply orig-fun `(,(seq-first command) ,(seq-rest command))))) ;;;; Minor mode @@ -139,8 +140,6 @@ If prefix-argument directly DETACH from the session." (remove-hook 'eshell-preoutput-filter-functions #'dtache--dtache-env-message-filter) (remove-hook 'eshell-preoutput-filter-functions #'dtache--dtach-eof-message-filter))) -(advice-add #'eshell-external-command :around #'dtache-eshell--external-command) - (provide 'dtache-eshell) ;;; dtache-eshell.el ends here diff --git a/dtache-extra.el b/dtache-extra.el new file mode 100644 index 0000000000..350f63ac0d --- /dev/null +++ b/dtache-extra.el @@ -0,0 +1,53 @@ +;;; dtache-extra.el --- Dtache integration for external packages -*- lexical-binding: t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; 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 <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package provides a collection of functionality to integrate `dtache' with external packages. + +;;; Code: + +;;;; Requirements + +(declare-function dtache-compile "dtache") +(declare-function dtache-start-session "dtache") + +(defvar dtache-session-origin) +(defvar dtache-local-session) + +;;;; Functions + +;;;###autoload +(defun dtache-extra-projectile-run-compilation (cmd &optional use-comint-mode) + "If CMD is a string execute it with `dtache-compile', optionally USE-COMINT-MODE." + (if (functionp cmd) + (funcall cmd) + (let ((dtache-session-origin 'projectile)) + (dtache-compile cmd use-comint-mode)))) + +;;;###autoload +(defun dtache-extra-dired-rsync (command _details) + "Run COMMAND with `dtache'." + (let ((dtache-local-session t) + (dtache-session-origin 'rsync)) + (dtache-start-session command t))) + +(provide 'dtache-extra) + +;;; dtache-extra.el ends here diff --git a/dtache-init.el b/dtache-init.el new file mode 100644 index 0000000000..f563873330 --- /dev/null +++ b/dtache-init.el @@ -0,0 +1,103 @@ +;;; dtache-init.el --- Initialize dtache -*- lexical-binding: t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; 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 <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This is intended to aid users in configuring `dtache's integration with other packages. + +;;; Code: + +;;;; Requirements + +(declare-function dtache-shell-mode "dtache") +(declare-function dtache-compile-start "dtache-compile") +(declare-function dtache-dired-do-shell-command "dtache-dired") +(declare-function dtache-eshell-mode "dtache-eshell") +(declare-function dtache-extra-projectile-run-compilation "dtache-extra") +(declare-function dtache-extra-dired-rsync "dtache-extra") +(declare-function dtache-org-babel-sh "dtache-org") +(declare-function dtache-shell-override-history "dtache-shell") +(declare-function dtache-shell-save-history-on-kill "dtache-shell") + +(declare-function org-babel-sh-evaluate "ob-shell") +(declare-function dired-rsync--do-run "dired-rsync") +(declare-function dired-rsync "dired-rsync") +(declare-function projectile "projectile") + +;;;; Variables + +(defvar dtache-package-integration '((compile . dtache-init-compile) + (dired . dtache-init-dired) + (dired-rsync . dtache-init-dired-rsync) + (eshell . dtache-init-eshell) + (org . dtache-init-org) + (projectile . dtache-init-projectile) + (shell . dtache-init-shell)) + "Alist which contain names of packages and their initialization function.") + +(defun dtache-init (&optional packages) + "Initialize `dtache' integration with all packages. + +Optionally provide a list of PACKAGES to enable integration for." + + ;; Required for `dtache-shell-command' which is always provided + (add-hook 'shell-mode-hook #'dtache-shell-mode) + + (let ((packages + (or packages + (seq-map #'car dtache-package-integration)))) + (dolist (package packages) + (funcall (alist-get package dtache-package-integration))))) + +(defun dtache-init-shell () + "Initialize integration with `shell'." + (advice-add #'shell :around #'dtache-shell-override-history) + (add-hook 'shell-mode-hook #'dtache-shell-save-history-on-kill)) + +(defun dtache-init-compile () + "Initialize integration with `compile'." + (add-hook 'compilation-start-hook #'dtache-compile-start) + (add-hook 'compilation-shell-minor-mode-hook #'dtache-shell-mode)) + +(defun dtache-init-eshell () + "Initialize integration with `eshell'." + (add-hook 'eshell-mode-hook #'dtache-eshell-mode)) + +(defun dtache-init-org () + "Initialize integration with `org'." + (advice-add #'org-babel-sh-evaluate :around #'dtache-org-babel-sh)) + +(defun dtache-init-dired () + "Initialize integration with `dired'." + (advice-add 'dired-do-shell-command :around #'dtache-dired-do-shell-command)) + +(defun dtache-init-dired-rsync () + "Initialize integration with `dired-rsync'." + (when (functionp #'dired-rsync) + (advice-add #'dired-rsync--do-run :override #'dtache-extra-dired-rsync))) + +(defun dtache-init-projectile () + "Initialize integration with `projectile'." + (when (functionp #'projectile) + (advice-add 'projectile-run-compilation + :override #'dtache-extra-projectile-run-compilation))) + +(provide 'dtache-init) + +;;; dtache-init.el ends here diff --git a/dtache-org.el b/dtache-org.el index dab1a33f93..c42e38694c 100644 --- a/dtache-org.el +++ b/dtache-org.el @@ -41,6 +41,7 @@ ;;;; Functions +;;;###autoload (defun dtache-org-babel-sh (org-babel-sh-evaluate-fun &rest args) "Modify ARGS before calling ORG-BABEL-SH-EVALUATE-FUN. diff --git a/dtache-shell.el b/dtache-shell.el index 27299236a7..03065e7fcd 100644 --- a/dtache-shell.el +++ b/dtache-shell.el @@ -122,6 +122,7 @@ cluttering the comint-history with dtach commands." dtache-shell-history-file))) (comint-write-input-ring))))) +;;;###autoload (defun dtache-shell-override-history (orig-fun &rest args) "Override history to read `dtache-shell-history-file' in ORIG-FUN with ARGS. @@ -130,6 +131,7 @@ This function also makes sure that the HISTFILE is disabled for local shells." (advice-add 'comint-read-input-ring :around #'dtache-shell--comint-read-input-ring-advice) (apply orig-fun args))) +;;;###autoload (defun dtache-shell-save-history-on-kill () "Add hook to save history when killing `shell' buffer." (add-hook 'kill-buffer-hook #'dtache-shell--save-history 0 t)) diff --git a/dtache-vterm.el b/dtache-vterm.el new file mode 100644 index 0000000000..573134afa3 --- /dev/null +++ b/dtache-vterm.el @@ -0,0 +1,97 @@ +;;; dtache-vterm.el --- Dtache integration with vterm -*- lexical-binding: t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; 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 <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package integrates `dtache' with `vterm' + +;;; Code: + +;;;; Requirements + +(require 'subr-x) + +(declare-function dtache-compile "dtache") +(declare-function dtache-get-sessions "dtache") +(declare-function dtache--host "dtache") +(declare-function dtache-dtach-command "dtache") +(declare-function dtache--session-host "dtache") +(declare-function dtache--determine-session-state "dtache") +(declare-function dtache-completing-read "dtache") + +(defvar dtache-session-origin) +(defvar dtache--dtach-detach-character) +(defvar dtache-session-action) +(defvar dtache-session-mode) + +(declare-function vterm-send-C-a "vterm") +(declare-function vterm-send-C-k "vterm") +(declare-function vterm-send-C-e "vterm") +(declare-function vterm-send-return "vterm") + +(defvar vterm--process) +(declare-function vterm-end-of-line "vterm") + +;;;; Functions + +;;;###autoload +(defun dtache-extra-vterm-send-input (&optional detach) + "Create a `dtache' session. + +Optionally DETACH from it." + (interactive) + (vterm-send-C-a) + (let* ((input (buffer-substring-no-properties (point) (vterm-end-of-line))) + (dtache-session-origin 'vterm) + (dtache-session-action + '(:attach dtache-shell-command-attach-session + :view dtache-view-dwim + :run dtache-shell-command)) + (dtache-session-mode + (if detach 'create 'create-and-attach))) + (vterm-send-C-k) + (process-send-string vterm--process (dtache-dtach-command input t)) + (vterm-send-C-e) + (vterm-send-return))) + +;;;###autoload +(defun dtache-extra-vterm-attach (session) + "Attach to an active `dtache' SESSION." + (interactive + (list + (let* ((host-name (car (dtache--host))) + (sessions + (thread-last (dtache-get-sessions) + (seq-filter (lambda (it) + (string= (car (dtache--session-host it)) host-name))) + (seq-filter (lambda (it) (eq 'active (dtache--determine-session-state it))))))) + (dtache-completing-read sessions)))) + (let ((dtache-session-mode 'attach)) + (process-send-string vterm--process (dtache-dtach-command session t)) + (vterm-send-return))) + +;;;###autoload +(defun dtache-extra-vterm-detach () + "Detach from a `dtache' session." + (interactive) + (process-send-string vterm--process dtache--dtach-detach-character)) + +(provide 'dtache-vterm) + +;;; dtache-vterm.el ends here diff --git a/dtache.el b/dtache.el index 0153a53f3d..dbb1a2991d 100644 --- a/dtache.el +++ b/dtache.el @@ -610,6 +610,7 @@ nil before closing." (dtache--watch-session-directory (dtache--session-directory session)) session))) +;;;###autoload (defun dtache-start-session (command &optional suppress-output) "Start a `dtache' session running COMMAND.