Better distrobox and sudo tramp support
This commit is contained in:
parent
6ea87de1b5
commit
b1d77b0f5d
@ -1,133 +0,0 @@
|
|||||||
;;; arch-ros2.el --- Activate and deactivate ROS2 dev environment on ArchLinux -*- lexical-binding: t -*-
|
|
||||||
;;; Commentary:
|
|
||||||
;;; Code:
|
|
||||||
(require 'cl-lib)
|
|
||||||
|
|
||||||
(defcustom arch-ros2-root "/opt/ros/humble/"
|
|
||||||
"Root directory of the ROS2 install."
|
|
||||||
:type 'directory
|
|
||||||
:group 'arch-ros2)
|
|
||||||
|
|
||||||
(defcustom arch-ros2-distro "humble"
|
|
||||||
"Version name of ROS2."
|
|
||||||
:type 'string
|
|
||||||
:group 'arch-ros2)
|
|
||||||
|
|
||||||
(defcustom arch-ros2-version 2
|
|
||||||
"Version number of ROS2 (probably 2)."
|
|
||||||
:type 'integer
|
|
||||||
:group 'arch-ros2)
|
|
||||||
|
|
||||||
(defcustom arch-ros2-python-version "3.13"
|
|
||||||
"Python version of ROS2."
|
|
||||||
:type 'string
|
|
||||||
:group 'arch-ros2)
|
|
||||||
|
|
||||||
(defvar arch-ros2-active nil
|
|
||||||
"Weather of not the ROS2 development environment is active.")
|
|
||||||
|
|
||||||
(defconst arch-ros2-mode-line-format `(arch-ros2-active
|
|
||||||
,(propertize "[ROS2]"
|
|
||||||
'face 'mode-line-emphasis))
|
|
||||||
"Mode line element for ROS2.")
|
|
||||||
|
|
||||||
(defvar arch-ros2--saved-env-vars (make-hash-table :test 'equal)
|
|
||||||
"Hash table of saved environment variables.
|
|
||||||
The key of each entry is the variable name. The value is a cons. The car is
|
|
||||||
either the symbol \\='value or \\='files. If it is \\='value, the cons is a
|
|
||||||
list of the old value and the value we installed. If the cdr is \\='files, the
|
|
||||||
value is a list of files to be removed from the variable.")
|
|
||||||
|
|
||||||
(defun arch-ros2--set-env-var (var value)
|
|
||||||
"Set the environment variable VAR to VALUE, saving its old value."
|
|
||||||
(puthash var (list 'value (getenv var) value) arch-ros2--saved-env-vars)
|
|
||||||
(setenv var value))
|
|
||||||
|
|
||||||
(defun arch-ros2--add-file-to-var (var &rest values)
|
|
||||||
"Add each of VALUES to the file list environment variable VAR.
|
|
||||||
This will prepend the values to VAR."
|
|
||||||
(let* ((cur-val (split-string (or (getenv var) "") ":" t))
|
|
||||||
(to-set))
|
|
||||||
(dolist (value values)
|
|
||||||
(unless (cl-find value cur-val :test 'equal)
|
|
||||||
(push value to-set)))
|
|
||||||
(let ((cache (gethash var arch-ros2--saved-env-vars)))
|
|
||||||
(puthash var (cons 'files (seq-uniq (append to-set (cdr cache))))
|
|
||||||
arch-ros2--saved-env-vars))
|
|
||||||
(setenv var (string-join (append to-set cur-val) ":"))))
|
|
||||||
|
|
||||||
(defun arch-ros2--add-to-path (&rest values)
|
|
||||||
"Add each of VALUES to the variable `exec-path'."
|
|
||||||
(let ((to-check (butlast exec-path))
|
|
||||||
(did-add nil))
|
|
||||||
(dolist (value values)
|
|
||||||
(unless (cl-find value to-check :test 'equal)
|
|
||||||
(push value exec-path)
|
|
||||||
(push value did-add)))
|
|
||||||
(puthash 'exec-path (append did-add
|
|
||||||
(gethash 'exec-path arch-ros2--saved-env-vars))
|
|
||||||
arch-ros2--saved-env-vars)))
|
|
||||||
|
|
||||||
(defun arch-ros2--restore-env-var (var)
|
|
||||||
"Restore the value of VAR set with `arch-ros2--set-env-var'."
|
|
||||||
(let ((entry (gethash var arch-ros2--saved-env-vars)))
|
|
||||||
(cl-case (car entry)
|
|
||||||
(value
|
|
||||||
(cl-destructuring-bind (&optional old-val our-val) (cdr entry)
|
|
||||||
;; don't restore values that have been changed
|
|
||||||
(when (equal our-val (getenv var))
|
|
||||||
(setenv var old-val))))
|
|
||||||
(files
|
|
||||||
(when-let ((cur-val (getenv var))
|
|
||||||
(parts (split-string cur-val ":" t)))
|
|
||||||
(setenv var (string-join (seq-difference parts (cdr entry)) ":")))))
|
|
||||||
(remhash var arch-ros2--saved-env-vars)))
|
|
||||||
|
|
||||||
(defun arch-ros2-activate ()
|
|
||||||
"Activate a ROS2 development environment."
|
|
||||||
(interactive)
|
|
||||||
(setq arch-ros2-active t)
|
|
||||||
(add-to-list 'mode-line-misc-info arch-ros2-mode-line-format)
|
|
||||||
(arch-ros2--add-to-path "/opt/ros/humble/bin/")
|
|
||||||
(arch-ros2--set-env-var "AMENT_PREFIX_PATH" arch-ros2-root)
|
|
||||||
(arch-ros2--set-env-var "CMAKE_PREFIX_PATH" arch-ros2-root)
|
|
||||||
(arch-ros2--set-env-var "COLCON_PREFIX_PATH" arch-ros2-root)
|
|
||||||
(arch-ros2--set-env-var "ROS_DISTRO" arch-ros2-distro)
|
|
||||||
(arch-ros2--set-env-var "ROS_LOCALHOST_ONLY" "0")
|
|
||||||
(arch-ros2--set-env-var "ROS_PYTHON_VERSION"
|
|
||||||
(car (split-string arch-ros2-python-version "\\.")))
|
|
||||||
(arch-ros2--set-env-var "ROS_VERSION"
|
|
||||||
(number-to-string arch-ros2-version))
|
|
||||||
(arch-ros2--add-file-to-var
|
|
||||||
"LD_LIBRARY_PATH"
|
|
||||||
(expand-file-name "opt/rviz_ogre_vendor/lib"
|
|
||||||
arch-ros2-root)
|
|
||||||
(expand-file-name "lib"
|
|
||||||
arch-ros2-root))
|
|
||||||
(arch-ros2--add-file-to-var
|
|
||||||
"PKG_CONFIG_PATH" (expand-file-name "lib/pkgconfig" arch-ros2-root))
|
|
||||||
(let ((python-dir (expand-file-name
|
|
||||||
(concat "lib/python" arch-ros2-python-version)
|
|
||||||
arch-ros2-root)))
|
|
||||||
(arch-ros2--add-file-to-var "PYTHONPATH"
|
|
||||||
(expand-file-name "dist-packages" python-dir)
|
|
||||||
(expand-file-name "site-packages" python-dir))))
|
|
||||||
|
|
||||||
(defun arch-ros2-deactivate ()
|
|
||||||
"Deactivate the ROS2 development environment."
|
|
||||||
(interactive)
|
|
||||||
(setq arch-ros2-active nil
|
|
||||||
mode-line-misc-info (cl-remove arch-ros2-mode-line-format
|
|
||||||
mode-line-misc-info
|
|
||||||
:test 'equal))
|
|
||||||
(maphash (lambda (k v)
|
|
||||||
(cond
|
|
||||||
((stringp k)
|
|
||||||
(arch-ros2--restore-env-var k))
|
|
||||||
((eq k 'exec-path)
|
|
||||||
(setq exec-path (seq-difference exec-path v))
|
|
||||||
(remhash 'exec-path arch-ros2--saved-env-vars))))
|
|
||||||
arch-ros2--saved-env-vars))
|
|
||||||
|
|
||||||
(provide 'arch-ros2)
|
|
||||||
;;; arch-ros2.el ends here
|
|
@ -5,6 +5,8 @@
|
|||||||
(require 'vc-git)
|
(require 'vc-git)
|
||||||
(require 'eshell)
|
(require 'eshell)
|
||||||
(require 'cl-lib)
|
(require 'cl-lib)
|
||||||
|
(require 'tramp)
|
||||||
|
(eval-when-compile (require 'rx))
|
||||||
|
|
||||||
;;; Configuration options
|
;;; Configuration options
|
||||||
(defgroup eshell-starship nil
|
(defgroup eshell-starship nil
|
||||||
@ -35,7 +37,7 @@ This will also update all eshell-starship explain buffers that need updating."
|
|||||||
(revert-buffer)))))))
|
(revert-buffer)))))))
|
||||||
|
|
||||||
(defcustom eshell-starship-module-order
|
(defcustom eshell-starship-module-order
|
||||||
'("remote" "cwd" "git" "vc" t "cmd-time" "arrow")
|
'("remote" "root" "cwd" "git" "vc" t "cmd-time" "newline" "container" "arrow")
|
||||||
"The order of modules for eshell-starship.
|
"The order of modules for eshell-starship.
|
||||||
This is a list with each element being a module name. The special value t can
|
This is a list with each element being a module name. The special value t can
|
||||||
appear at most once to denote \"all remaining modules\"."
|
appear at most once to denote \"all remaining modules\"."
|
||||||
@ -58,6 +60,22 @@ appear at most once to denote \"all remaining modules\"."
|
|||||||
:tag "Suppress eshell-starship explore refresh messages"
|
:tag "Suppress eshell-starship explore refresh messages"
|
||||||
:type 'boolean)
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom eshell-starship-overridden-remote-methods
|
||||||
|
'("docker" "podman" "kubernetes" "doas" "su" "sudo" "sudoedit")
|
||||||
|
"List of `file-remote-p' mwthods that should NOT be considered remote.
|
||||||
|
Any eshell buffer with a `default-directory' managed by one of these methods
|
||||||
|
will not be considered remote and all modules that would be disabled because of
|
||||||
|
the remote directory will work as usual."
|
||||||
|
:group 'eshell-starship
|
||||||
|
:tag "Overridden Remote Methods"
|
||||||
|
:type '(repeat (string :tag "Method")))
|
||||||
|
|
||||||
|
(defcustom eshell-starship-verbose-tramp 1
|
||||||
|
"Tramp verbosity level when rendering the prompt."
|
||||||
|
:group 'eshell-starship
|
||||||
|
:tag "Tramp Verbosity Level"
|
||||||
|
:type 'integer)
|
||||||
|
|
||||||
(defface eshell-starship-icon-face '((t :inherit default))
|
(defface eshell-starship-icon-face '((t :inherit default))
|
||||||
"Face to use when drawing module icons.
|
"Face to use when drawing module icons.
|
||||||
Note that the foreground color will be overridden by the module."
|
Note that the foreground color will be overridden by the module."
|
||||||
@ -162,7 +180,7 @@ be nil.")
|
|||||||
:documentation "Weather the module should be run if
|
:documentation "Weather the module should be run if
|
||||||
`default-directory' is a `file-remote-p'.")
|
`default-directory' is a `file-remote-p'.")
|
||||||
(action :initarg :action
|
(action :initarg :action
|
||||||
:initform 'ignore
|
:initform 'string
|
||||||
:accessor eshell-starship-module-action
|
:accessor eshell-starship-module-action
|
||||||
:type function
|
:type function
|
||||||
:documentation "A function that produces the main text for the
|
:documentation "A function that produces the main text for the
|
||||||
@ -304,11 +322,15 @@ Example:
|
|||||||
(defun eshell-starship--get-current-dir ()
|
(defun eshell-starship--get-current-dir ()
|
||||||
"Get dir for `eshell-starship--prompt-function'."
|
"Get dir for `eshell-starship--prompt-function'."
|
||||||
(concat
|
(concat
|
||||||
(propertize (eshell-starship--limit-path-parts
|
(propertize
|
||||||
3 (if-let ((worktree (vc-root-dir))
|
(eshell-starship--limit-path-parts
|
||||||
|
3 (let ((cwd (or (file-remote-p default-directory 'localname)
|
||||||
|
default-directory)))
|
||||||
|
(if-let ((worktree (vc-root-dir))
|
||||||
(parent (file-name-parent-directory worktree)))
|
(parent (file-name-parent-directory worktree)))
|
||||||
(file-relative-name default-directory parent)
|
(file-relative-name cwd (or (file-remote-p parent 'localname)
|
||||||
(eshell-starship--replace-home-with-tilda default-directory)))
|
parent))
|
||||||
|
(eshell-starship--replace-home-with-tilda cwd))))
|
||||||
'face '(:foreground "dark turquoise"))
|
'face '(:foreground "dark turquoise"))
|
||||||
(unless (file-writable-p default-directory)
|
(unless (file-writable-p default-directory)
|
||||||
" ")))
|
" ")))
|
||||||
@ -721,24 +743,56 @@ This does not mean anything if pyenv-mode is not installed.")
|
|||||||
|
|
||||||
;;; Misc modules
|
;;; Misc modules
|
||||||
(eshell-starship-defmodule remote
|
(eshell-starship-defmodule remote
|
||||||
:icon "🌐"
|
:icon "🌐 "
|
||||||
:color "light blue"
|
:color "light blue"
|
||||||
:predicate (lambda ()
|
:predicate
|
||||||
(file-remote-p default-directory))
|
(lambda ()
|
||||||
|
(eshell-starship--remote-for-modules-p default-directory))
|
||||||
|
:action
|
||||||
|
(lambda ()
|
||||||
|
(or (file-remote-p default-directory 'host) ""))
|
||||||
|
:reload-on 'cwd
|
||||||
:doc "A small icon if the working directory is remote.")
|
:doc "A small icon if the working directory is remote.")
|
||||||
|
|
||||||
|
(eshell-starship-defmodule root
|
||||||
|
:predicate
|
||||||
|
(lambda ()
|
||||||
|
(member (file-remote-p default-directory 'method)
|
||||||
|
'("doas" "sudo" "su" "sudoedit")))
|
||||||
|
:action
|
||||||
|
(lambda ()
|
||||||
|
(format "%s in"
|
||||||
|
(propertize (file-remote-p default-directory 'user)
|
||||||
|
'face '(:weight bold :foreground "red"))))
|
||||||
|
:reload-on 'cwd
|
||||||
|
:doc "Show the current sudo or doas user.")
|
||||||
|
|
||||||
|
(eshell-starship-defmodule newline
|
||||||
|
:predicate 'always
|
||||||
|
:action (lambda () (propertize "\n" 'read-only t 'rear-nonsticky t))
|
||||||
|
:doc "A newline in the prompt.")
|
||||||
|
|
||||||
|
(eshell-starship-defmodule container
|
||||||
|
:icon "⬢ "
|
||||||
|
:color "firebrick"
|
||||||
|
:predicate (lambda ()
|
||||||
|
(member (file-remote-p default-directory 'method)
|
||||||
|
'("docker" "podman" "kubernetes")))
|
||||||
|
:action (lambda ()
|
||||||
|
(format "[%s]" (file-remote-p default-directory 'host)))
|
||||||
|
:reload-on 'cwd
|
||||||
|
:doc "The name of the current container.")
|
||||||
|
|
||||||
(eshell-starship-defmodule arrow
|
(eshell-starship-defmodule arrow
|
||||||
:predicate 'always
|
:predicate 'always
|
||||||
:reload-on 'always
|
:reload-on 'always
|
||||||
:action (lambda ()
|
:action (lambda ()
|
||||||
(concat
|
|
||||||
(propertize "\n" 'read-only t 'rear-nonsticky t)
|
|
||||||
(propertize
|
(propertize
|
||||||
"❯ " 'face `(:foreground
|
"❯ " 'face `(:foreground
|
||||||
,(if (= eshell-last-command-status 0)
|
,(if (= eshell-last-command-status 0)
|
||||||
"lime green"
|
"lime green"
|
||||||
"red"))
|
"red"))
|
||||||
'rear-nonsticky t)))
|
'rear-nonsticky t))
|
||||||
:doc "An arrow that appears next to where you type.")
|
:doc "An arrow that appears next to where you type.")
|
||||||
|
|
||||||
|
|
||||||
@ -773,10 +827,20 @@ That is, if EXT is \"pkg.tar.gz\", this will return
|
|||||||
(substring name (1+ idx))
|
(substring name (1+ idx))
|
||||||
""))
|
""))
|
||||||
|
|
||||||
|
(defun eshell-starship--remote-for-modules-p (file)
|
||||||
|
"Return non-nil if FILE is remote for the purpose of running modules."
|
||||||
|
(let ((method (file-remote-p file 'method)))
|
||||||
|
(and method
|
||||||
|
(not (member method eshell-starship-overridden-remote-methods)))))
|
||||||
|
|
||||||
(defun eshell-starship--modules-for-dir (dir)
|
(defun eshell-starship--modules-for-dir (dir)
|
||||||
"Return a list of modules that are applicable to DIR."
|
"Return a list of modules that are applicable to DIR."
|
||||||
|
(let ((is-remote (eshell-starship--remote-for-modules-p dir)))
|
||||||
(seq-uniq
|
(seq-uniq
|
||||||
(nconc
|
(nconc
|
||||||
|
(cl-delete-if
|
||||||
|
(lambda (module)
|
||||||
|
(and is-remote (not (eshell-starship-module-allow-remote-p module))))
|
||||||
(mapcan
|
(mapcan
|
||||||
(lambda (entry)
|
(lambda (entry)
|
||||||
(let ((name (car entry))
|
(let ((name (car entry))
|
||||||
@ -790,19 +854,25 @@ That is, if EXT is \"pkg.tar.gz\", this will return
|
|||||||
:extensions ext)))
|
:extensions ext)))
|
||||||
(eshell-starship--permute-extension
|
(eshell-starship--permute-extension
|
||||||
(eshell-starship--file-name-extension name)))))))
|
(eshell-starship--file-name-extension name)))))))
|
||||||
(directory-files-and-attributes dir nil nil t))
|
(directory-files-and-attributes dir nil nil t)))
|
||||||
(let ((default-directory dir))
|
(let ((default-directory dir))
|
||||||
(cl-loop for (name is-dir module) in eshell-starship--extra-module-files
|
(cl-loop for (name is-dir module) in eshell-starship--extra-module-files
|
||||||
when (and is-dir (file-directory-p name))
|
when (and (or (not is-remote)
|
||||||
|
(eshell-starship-module-allow-remote-p module))
|
||||||
|
is-dir (file-directory-p name))
|
||||||
collect module
|
collect module
|
||||||
when (and (not is-dir) (file-exists-p name))
|
when (and (or (not is-remote)
|
||||||
|
(eshell-starship-module-allow-remote-p module))
|
||||||
|
(not is-dir) (file-exists-p name))
|
||||||
collect module))
|
collect module))
|
||||||
(let ((default-directory dir))
|
(let ((default-directory dir))
|
||||||
(cl-loop for module being the hash-values of eshell-starship-modules
|
(cl-loop for module being the hash-values of eshell-starship-modules
|
||||||
for predicate = (eshell-starship-module-predicate module)
|
for predicate = (eshell-starship-module-predicate module)
|
||||||
when (funcall predicate)
|
when (and (or (not is-remote)
|
||||||
|
(eshell-starship-module-allow-remote-p module))
|
||||||
|
(funcall predicate))
|
||||||
collect module)))
|
collect module)))
|
||||||
'eq))
|
'eq)))
|
||||||
|
|
||||||
(defun eshell-starship--propertize-face (str append &rest faces)
|
(defun eshell-starship--propertize-face (str append &rest faces)
|
||||||
"Copy STR and add FACES to its text properties.
|
"Copy STR and add FACES to its text properties.
|
||||||
@ -902,9 +972,17 @@ Return a hash table mapping module names to their output."
|
|||||||
(t
|
(t
|
||||||
(push (gethash cur-name output) pre)
|
(push (gethash cur-name output) pre)
|
||||||
(remhash cur-name output))))
|
(remhash cur-name output))))
|
||||||
(mapconcat 'identity
|
(cl-loop for (part . rest) = (nconc (nreverse pre)
|
||||||
(nconc (nreverse pre) (hash-table-values output) (nreverse post))
|
(hash-table-values output)
|
||||||
" ")))
|
(nreverse post))
|
||||||
|
then rest
|
||||||
|
while part
|
||||||
|
concat part
|
||||||
|
unless (or (string-suffix-p "\n" part)
|
||||||
|
(string-empty-p part)
|
||||||
|
(not (car rest))
|
||||||
|
(string-prefix-p "\n" (car rest)))
|
||||||
|
concat " ")))
|
||||||
|
|
||||||
(defun eshell-starship--render-prompt ()
|
(defun eshell-starship--render-prompt ()
|
||||||
"Actually produce the prompt."
|
"Actually produce the prompt."
|
||||||
@ -918,7 +996,8 @@ Return a hash table mapping module names to their output."
|
|||||||
|
|
||||||
(defun eshell-starship--prompt-function ()
|
(defun eshell-starship--prompt-function ()
|
||||||
"Function for `eshell-prompt-function'."
|
"Function for `eshell-prompt-function'."
|
||||||
(let (start-time prompt end-time)
|
(let ((tramp-verbose eshell-starship-verbose-tramp)
|
||||||
|
start-time prompt end-time)
|
||||||
(setq start-time (float-time)
|
(setq start-time (float-time)
|
||||||
prompt (eshell-starship--render-prompt)
|
prompt (eshell-starship--render-prompt)
|
||||||
end-time (float-time)
|
end-time (float-time)
|
||||||
@ -940,9 +1019,11 @@ Return a hash table mapping module names to their output."
|
|||||||
(defun eshell-starship--enable ()
|
(defun eshell-starship--enable ()
|
||||||
"Enable eshell-starship."
|
"Enable eshell-starship."
|
||||||
(setq-local eshell-starship--restore-state
|
(setq-local eshell-starship--restore-state
|
||||||
(buffer-local-set-state eshell-prompt-function
|
(buffer-local-set-state
|
||||||
|
eshell-prompt-function
|
||||||
'eshell-starship--prompt-function
|
'eshell-starship--prompt-function
|
||||||
eshell-prompt-regexp "^❯ "
|
;; temporary fix until the next version where eshell uses fields
|
||||||
|
eshell-prompt-regexp (rx bol (? "⬢ [" (+ any) "] ") "❯ ")
|
||||||
eshell-highlight-prompt nil)
|
eshell-highlight-prompt nil)
|
||||||
eshell-starship--module-cache (make-hash-table :test 'equal))
|
eshell-starship--module-cache (make-hash-table :test 'equal))
|
||||||
(add-hook 'eshell-pre-command-hook
|
(add-hook 'eshell-pre-command-hook
|
||||||
|
161
init.el
161
init.el
@ -227,12 +227,32 @@ Interactively, force the recompile if called with a prefix."
|
|||||||
(use-package tramp
|
(use-package tramp
|
||||||
:ensure nil
|
:ensure nil
|
||||||
:config
|
:config
|
||||||
|
(add-to-list 'tramp-connection-properties
|
||||||
|
(list (rx bos "/" (or "podman" "docker") ":")
|
||||||
|
"direct-async-process" t))
|
||||||
|
(add-to-list 'tramp-connection-properties
|
||||||
|
(list (rx bos "/" (or "ssh" "sshx") ":")
|
||||||
|
"direct-async-process" t))
|
||||||
|
(add-to-list 'tramp-connection-properties
|
||||||
|
(list (rx bos "/" (or "sudo" "su" "doas"
|
||||||
|
"sudoedit")
|
||||||
|
":")
|
||||||
|
"direct-async-process" t))
|
||||||
(connection-local-set-profile-variables
|
(connection-local-set-profile-variables
|
||||||
'remote-direct-async-process
|
'error-only
|
||||||
'((tramp-direct-async-process . t)))
|
'((tramp-verbose . 1)))
|
||||||
(connection-local-set-profiles
|
(connection-local-set-profiles
|
||||||
'(:protocol "ssh")
|
'(:method "sudo")
|
||||||
'remote-direct-async-process))
|
'error-only)
|
||||||
|
(connection-local-set-profiles
|
||||||
|
'(:method "doas")
|
||||||
|
'error-only)
|
||||||
|
(connection-local-set-profiles
|
||||||
|
'(:method "su")
|
||||||
|
'error-only)
|
||||||
|
(connection-local-set-profiles
|
||||||
|
'(:method "sudoedit")
|
||||||
|
'error-only))
|
||||||
|
|
||||||
(use-package midnight
|
(use-package midnight
|
||||||
:ensure nil
|
:ensure nil
|
||||||
@ -1762,9 +1782,6 @@ otherwise, call `bibtex-find-text'."
|
|||||||
(use-package pyvenv)
|
(use-package pyvenv)
|
||||||
(use-package pyenv-mode)
|
(use-package pyenv-mode)
|
||||||
|
|
||||||
;; My dev environment for ROS2
|
|
||||||
(require 'arch-ros2)
|
|
||||||
|
|
||||||
;; java-ts-mode
|
;; java-ts-mode
|
||||||
(use-package java-ts-mode
|
(use-package java-ts-mode
|
||||||
:hook ((java-ts-mode . trusted-files-eglot-ensure-if-safe)
|
:hook ((java-ts-mode . trusted-files-eglot-ensure-if-safe)
|
||||||
@ -2464,7 +2481,7 @@ argument."
|
|||||||
:hook ((eshell-load . eat-eshell-visual-command-mode)
|
:hook ((eshell-load . eat-eshell-visual-command-mode)
|
||||||
(eshell-mode . eat-eshell-mode)
|
(eshell-mode . eat-eshell-mode)
|
||||||
(eshell-mode . my/-eshell-mode-setup)
|
(eshell-mode . my/-eshell-mode-setup)
|
||||||
(eshell-directory-change . my/-eshell-maybe-setup-remote-aliases))
|
(eshell-directory-change . my/-eshell-maybe-setup-remote))
|
||||||
:bind (:map eshell-mode-map
|
:bind (:map eshell-mode-map
|
||||||
("TAB" . completion-at-point)
|
("TAB" . completion-at-point)
|
||||||
("<tab>" . completion-at-point))
|
("<tab>" . completion-at-point))
|
||||||
@ -2479,14 +2496,73 @@ argument."
|
|||||||
(or " " eos))
|
(or " " eos))
|
||||||
(cl-second elt))))
|
(cl-second elt))))
|
||||||
eshell-command-aliases-list))
|
eshell-command-aliases-list))
|
||||||
(defun my/-eshell-maybe-setup-remote-aliases ()
|
|
||||||
(if (file-remote-p default-directory)
|
(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)
|
||||||
|
(eshell/-captive-cd "~"))
|
||||||
|
((or (not (file-remote-p default-directory))
|
||||||
|
(file-remote-p dir))
|
||||||
|
(eshell/cd dir))
|
||||||
|
((file-name-absolute-p dir)
|
||||||
|
(eshell/cd (concat (file-remote-p default-directory) dir)))
|
||||||
|
(t
|
||||||
|
(eshell/cd dir))))
|
||||||
|
|
||||||
|
(defvar-local my/-eshell-last-remote-system nil)
|
||||||
|
(defun my/-eshell-maybe-setup-remote (&optional force)
|
||||||
|
(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)
|
||||||
(setq-local eshell-command-aliases-list (my/-eshell-filter-alias-list))
|
(setq-local eshell-command-aliases-list (my/-eshell-filter-alias-list))
|
||||||
(kill-local-variable 'eshell-command-aliases-list)))
|
(setq-local eshell-command-aliases-list
|
||||||
|
(default-toplevel-value 'eshell-command-aliases-list)))
|
||||||
|
(setq-local eshell-command-aliases-list
|
||||||
|
(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))
|
||||||
|
(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)
|
||||||
|
(unless (executable-find "eza" t)
|
||||||
|
(if (executable-find "exa" t)
|
||||||
|
(setf (alist-get "ls" eshell-command-aliases-list nil nil 'equal)
|
||||||
|
'("exa -F $*"))
|
||||||
|
(setf (alist-get "ls" eshell-command-aliases-list nil t 'equal)
|
||||||
|
nil)))
|
||||||
|
(unless (executable-find "trash-put" t)
|
||||||
|
(setf (alist-get "tp" eshell-command-aliases-list nil t 'equal) nil
|
||||||
|
(alist-get "trr" eshell-command-aliases-list nil t 'equal) nil
|
||||||
|
(alist-get "tre" eshell-command-aliases-list nil t 'equal) nil
|
||||||
|
(alist-get "trm" eshell-command-aliases-list nil t 'equal) nil
|
||||||
|
(alist-get "rm" eshell-command-aliases-list nil t 'equal) nil))
|
||||||
|
(setf (alist-get "ldg" eshell-command-aliases-list nil t 'equal) nil)))
|
||||||
|
(setq-local my/-eshell-last-remote-system
|
||||||
|
(file-remote-p default-directory)))
|
||||||
|
|
||||||
(defun my/-eshell-mode-setup ()
|
(defun my/-eshell-mode-setup ()
|
||||||
"Setup function run from `eshell-mode-hook'"
|
"Setup function run from `eshell-mode-hook'"
|
||||||
(setq-local corfu-auto nil)
|
(setq-local corfu-auto nil)
|
||||||
(my/-eshell-maybe-setup-remote-aliases))
|
(my/-eshell-maybe-setup-remote t))
|
||||||
(setq-default eshell-command-aliases-list
|
(setq-default eshell-command-aliases-list
|
||||||
'(("clear" "clear t")
|
'(("clear" "clear t")
|
||||||
("e" "find-file $1")
|
("e" "find-file $1")
|
||||||
@ -2507,10 +2583,10 @@ argument."
|
|||||||
("tp" "trash-put $*")
|
("tp" "trash-put $*")
|
||||||
("trr" "trash-restore $*")
|
("trr" "trash-restore $*")
|
||||||
("tre" "trash-empty $*")
|
("tre" "trash-empty $*")
|
||||||
("tre" "trash-empty $*")
|
|
||||||
("trm" "trash-rm $*")
|
("trm" "trash-rm $*")
|
||||||
("rm" "echo 'rm: I''m unsafe! Don''t use me.'; false")
|
("rm" "echo 'rm: I''m unsafe! Don''t use me.'; false")
|
||||||
("\\rm" "eshell/rm")))
|
("\\rm" "eshell/rm")))
|
||||||
|
|
||||||
(defvar my/eshell-bm-auto-ls t
|
(defvar my/eshell-bm-auto-ls t
|
||||||
"Weather or not to run ls after `eshell/bm'")
|
"Weather or not to run ls after `eshell/bm'")
|
||||||
(defun eshell/bm (&optional name)
|
(defun eshell/bm (&optional name)
|
||||||
@ -2518,10 +2594,61 @@ argument."
|
|||||||
If no name is given, list all bookmarks instead."
|
If no name is given, list all bookmarks instead."
|
||||||
(if name
|
(if name
|
||||||
(progn
|
(progn
|
||||||
(eshell/cd (bookmark-get-filename name))
|
(string-match (rx bos (group (* (not "/"))) (* "/") (group (* any)))
|
||||||
|
name)
|
||||||
|
(let* ((bm-name (match-string 1 name))
|
||||||
|
(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)
|
||||||
|
(setq full-path (concat (file-remote-p default-directory)
|
||||||
|
full-path)))
|
||||||
|
(if (not (file-directory-p full-path))
|
||||||
|
(progn
|
||||||
|
(find-file full-path)
|
||||||
|
(goto-char (bookmark-get-position bm-name)))
|
||||||
|
(eshell/cd full-path)
|
||||||
(when my/eshell-bm-auto-ls
|
(when my/eshell-bm-auto-ls
|
||||||
(eshell/ls)))
|
(eshell/ls)))))
|
||||||
(eshell-print (string-join (bookmark-all-names) " ")))))
|
(bookmark-maybe-load-default-file)
|
||||||
|
(eshell-print
|
||||||
|
(mapconcat (lambda (record)
|
||||||
|
(let ((name (bookmark-name-from-full-record record))
|
||||||
|
(file (bookmark-get-filename record)))
|
||||||
|
(format "%s => %s"
|
||||||
|
(propertize name 'face '(:foreground "deep sky blue"
|
||||||
|
:weight bold))
|
||||||
|
(if (file-directory-p file)
|
||||||
|
(file-name-as-directory file)
|
||||||
|
(directory-file-name file)))))
|
||||||
|
bookmark-alist
|
||||||
|
"\n"))))
|
||||||
|
(defun pcomplete/bm ()
|
||||||
|
"Completions for `bm'."
|
||||||
|
(let ((arg (pcomplete-arg)))
|
||||||
|
(if (not (cl-find ?/ arg))
|
||||||
|
(pcomplete-here (mapcar (##concat % "/") (bookmark-all-names)))
|
||||||
|
(when (string-match (rx bos (group (+ (not "/"))) (+ "/") (group (* any)))
|
||||||
|
arg)
|
||||||
|
(let ((bm-name (match-string 1 arg))
|
||||||
|
(after-path (match-string 2 arg)))
|
||||||
|
(when-let ((base (ignore-errors (bookmark-get-filename bm-name)))
|
||||||
|
((file-directory-p base))
|
||||||
|
(abs-path (expand-file-name after-path base))
|
||||||
|
(dir-path (if (string-empty-p after-path)
|
||||||
|
abs-path
|
||||||
|
(file-name-directory abs-path)))
|
||||||
|
(path-end (if (string-empty-p after-path)
|
||||||
|
""
|
||||||
|
(file-name-nondirectory abs-path))))
|
||||||
|
(pcomplete-here
|
||||||
|
(mapcan (lambda (entry)
|
||||||
|
(unless (member (car entry) '(".." "."))
|
||||||
|
(if (eq t (file-attribute-type (cdr entry)))
|
||||||
|
(list (concat (car entry) "/"))
|
||||||
|
(list (car entry)))))
|
||||||
|
(directory-files-and-attributes dir-path))
|
||||||
|
path-end))))))))
|
||||||
(use-package esh-help
|
(use-package esh-help
|
||||||
:hook (eshell-mode . my/-setup-eshell-help-func)
|
:hook (eshell-mode . my/-setup-eshell-help-func)
|
||||||
:init
|
:init
|
||||||
@ -2547,7 +2674,7 @@ 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
|
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)."
|
functions (only eshell uses it at the time of writing)."
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
(if (file-remote-p default-directory)
|
(if (my/-eshell-really-remote-p)
|
||||||
(my/project-eat-or-default)
|
(my/project-eat-or-default)
|
||||||
(my/project-eshell-or-default arg)))
|
(my/project-eshell-or-default arg)))
|
||||||
(keymap-global-set "C-c v" #'my/open-shell-dwim)
|
(keymap-global-set "C-c v" #'my/open-shell-dwim)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user