[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Advice on custom packages that conflict with tramp
From: |
Stefan Monnier |
Subject: |
Re: Advice on custom packages that conflict with tramp |
Date: |
Fri, 10 Mar 2023 11:19:18 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) |
> One of the Tramp team members took a brief look at my packages and said
> that he did see at least one oddity in how I'm creating the shell buffers,
> being that it creates the shell buffer (so I can control the name) and then
> calls "shell" for that buffer.
I can't see where it "creates the shell buffer" before calling `shell`.
> (defun cycle-make-shell ()
> "Implements a ring of *shell* buffers. If current buffer is not a shell
> buffer, then it will just execute 'shell'. If it IS a shell buffer, then
> create a new shell buffer, starting with '*shell-1*', but skipping to the
> next
> number if that already exists."
> (interactive)
> (let* ((bufname (buffer-name (current-buffer))))
> (if (string-match "\*shell\\(\*\\|-\\([0-9][0-9]*\\)\*\\)" bufname)
^ ^ ^
ineffective
BTW, why not check (derived-mode-p 'shell-mode) instead of checking the name?
> (progn
> (setq change-dir default-directory)
> (setq done nil)
Here you change those two *global* variables. Better define them
locally with `let`. *Never* use `setq` on a variable unless you've
locally defined it with `let` or you globally defined it with `defvar`.
I recommend you regularly byte-compile your code (or use `flymake-mode`)
to benefit from the compiler's warnings.
> (while (not done)
> (progn
> (setq new-bufname (next-bufname bufname "shell"))
> (if (bufferp (get-buffer new-bufname))
> (setq bufname new-bufname)
> (setq done t)
> )
> )
> )
> (if (bufferp (get-buffer "*shell*"))
> (progn
> (set-buffer "*shell*")
> (rename-uniquely)
> (setq tmp-bufname (buffer-name))
> ))
> (shell)
> (sit-for 1)
> (set-buffer "*shell*")
> (rename-buffer new-bufname)
> ;; Now we need to somehow change the directory to "change-dir".
> (set-buffer tmp-bufname)
> (rename-buffer "*shell*")
> (set-buffer new-bufname)
If I were you, I'd change that function so that all your buffers are
named `*shell-N*` (i.e. you won't have one called `*shell*` any more).
Then you can just replace the above code with something like:
(shell)
(rename-uniquely)
and call it a day. It makes the other case (i.e. when you call that
command from a non-shell buffer) slightly more complicated since you
have to look for a shell buffer, but nothing too bad.
IOW something like:
(defun my-cycle-make-shell ()
(interactive)
(let ((dest nil))
(unless (derived-mode-p 'shell-mode)
(let ((bufs (buffer-list)))
(while (and bufs (not dest))
(if (with-current-buffer (car bufs)
(derived-mode-p 'shell-mode))
(setq dest (car bufs))
(setq bufs (cdr bufs))))))
(if dest
(pop-to-buffer-same-window dest)
(shell)
(rename-uniquely))))
Of course, you can use something else than `rename-uniquely` if you
don't like the names it chooses :-)
> (defun cycle-find-shell (&optional string)
> (interactive "sEnter directory substring: ")
AFAICT `string` is actually not searched as a substring but as a regexp.
Stefan