Compare commits

..

4 commits

Author SHA1 Message Date
Howard Abrams
bd69943337 Add Tramp features and efficiencies 2025-09-05 10:39:20 -07:00
Howard Abrams
c7049e12e0 Add Python virtual environment to iTerm Status Bar
Which requires changes/additions to the Zshell world.
2025-09-05 10:39:20 -07:00
Howard Abrams
6da8591a1d Add better coloring to Pud connections 2025-09-01 22:44:49 -07:00
Howard Abrams
b171fbc3bf Fix connection issues in Mud client 2025-09-01 22:44:49 -07:00
6 changed files with 168 additions and 22 deletions

View file

@ -179,8 +179,17 @@ Ive often called =imenu= to easily jump to a function definition in a file (o
*** Remote Files *** Remote Files
To speed up TRAMP access, lets disabled lock files, you know, the ones that have the =#= surrounding characters: To speed up TRAMP access, lets disabled lock files, you know, the ones that have the =#= surrounding characters:
#+begin_src emacs-lisp #+begin_src emacs-lisp
(setq remote-file-name-inhibit-locks t) (setq remote-file-name-inhibit-locks t
tramp-use-scp-direct-remote-copying t
remote-file-name-inhibit-auto-save-visited t)
#+end_src #+end_src
According to [[https://coredumped.dev/2025/06/18/making-tramp-go-brrrr./][this essay]], Emacs should copy much larger files than the default:
#+BEGIN_SRC emacs-lisp
(setq tramp-copy-size-limit (* 1024 1024) ;; 1MB
tramp-verbose 2)
#+END_SRC
What do I think about [[elisp:(describe-variable 'remote-file-name-inhibit-auto-save-visited)][remote-file-name-inhibit-auto-save-visited]]? What do I think about [[elisp:(describe-variable 'remote-file-name-inhibit-auto-save-visited)][remote-file-name-inhibit-auto-save-visited]]?
During remote access, TRAMP can slow down performing Git operations. Lets turn that off as well: During remote access, TRAMP can slow down performing Git operations. Lets turn that off as well:

View file

@ -44,6 +44,7 @@ While Emacs supplies a Python editing environment, well still use =use-packag
(flycheck-add-next-checker 'python-pylint 'python-pycompile 'append)) (flycheck-add-next-checker 'python-pylint 'python-pycompile 'append))
#+end_src #+end_src
** Keybindings ** Keybindings
Instead of memorizing all the Emacs-specific keybindings, we use [[https://github.com/jerrypnz/major-mode-hydra.el][major-mode-hydra]] defined for =python-mode=: Instead of memorizing all the Emacs-specific keybindings, we use [[https://github.com/jerrypnz/major-mode-hydra.el][major-mode-hydra]] defined for =python-mode=:
@ -136,11 +137,64 @@ Next, after reading David Vujics [[https://davidvujic.blogspot.com/2025/03/ar
#+END_SRC #+END_SRC
** Virtual Environment ** Virtual Environment
When you need a particular version of Python, use [[https://github.com/pyenv/pyenv][pyenv]] globally: Use the built-in module, venv, to create isolated Python environments for specific projects, enabling you to manage dependencies separately.
Create a virtual environment, either in the projects directory, or in a global spot:
#+BEGIN_SRC sh
python3 -m venv .venv
#
python3 -m venv ~/.venv/my_project/
#+END_SRC
And then activate it:
#+BEGIN_SRC sh
source ~/.venv/my_project/bin/activate
#+END_SRC
Or add that to a projects' =.envrc=.
Now, do what you need to do with this isolation:
#+BEGIN_SRC sh :tangle no
pip install -r test-requirements.txt
#+END_SRC
** Virtual Environment with new Python Version
Pyenv is a tool for managing multiple versions of Python on your machine, allowing you to switch between them easily. On a Mac, installed it via Homebrew:
#+BEGIN_SRC sh
brew install readline xz
brew install pyenv pyenv-virtualenv
#+END_SRC
Or on other systems, use the /system/ Python to install [[https://github.com/pyenv/pyenv][pyenv]] globally:
#+begin_src sh #+begin_src sh
pip install pyenv pip install pyenv
#+end_src #+end_src
Make sure we load this in [[file:zshell.org::*Python][the Zsh profile]]:
#+BEGIN_SRC sh
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
#+END_SRC
Install the python versions you need, for instance:
#+BEGIN_SRC sh
pyenv install 3.9.23
#+END_SRC
Run =pyenv versions= to see what you have installed.
In any particular project directory, use a version you installed by creating a =.python-version= file, or call:
#+BEGIN_SRC sh
pyenv local 3.9.23
#+END_SRC
And have this in your =.envrc= file for use with [[file:ha-programming.org::*Virtual Environments with direnv][direnv]]: And have this in your =.envrc= file for use with [[file:ha-programming.org::*Virtual Environments with direnv][direnv]]:
#+begin_src conf #+begin_src conf
use python 3.7.1 use python 3.7.1
@ -257,6 +311,16 @@ Lets expand our =major-mode-hydra= with some extras:
("D" elpy-doc "Docs Symbol"))))) ("D" elpy-doc "Docs Symbol")))))
#+end_src #+end_src
* Anaconda
The [[https://github.com/pythonic-emacs/anaconda-mode][anaconda-mode project]] seems as good as Elpy, but also include Evil keybindings.
#+BEGIN_SRC emacs-lisp :tangle no
(use-mode anaconda-mode
:hook ((python-mode . anaconda-mode)
(python-mode ../ anaconda-eldoc-mode)))
#+END_SRC
Since we are using
* LSP Integration of Python * LSP Integration of Python
** Dependencies ** Dependencies
Each Python project's =requirements-dev.txt= file would reference the [[https://pypi.org/project/python-lsp-server/][python-lsp-server]] (not the /unmaintained/ project, =python-language-server=): Each Python project's =requirements-dev.txt= file would reference the [[https://pypi.org/project/python-lsp-server/][python-lsp-server]] (not the /unmaintained/ project, =python-language-server=):

61
pud.org
View file

@ -2,7 +2,7 @@
#+author: Howard X. Abrams #+author: Howard X. Abrams
#+date: 2025-01-18 #+date: 2025-01-18
#+filetags: emacs hamacs #+filetags: emacs hamacs
#+lastmod: [2025-08-05 Tue] #+lastmod: [2025-08-23 Sat]
A literate programming file for a Comint-based MUD client. A literate programming file for a Comint-based MUD client.
@ -104,10 +104,27 @@ You will want to customize your connections to the connections, as this program
For instance, you could set up a call to =setopt= or customize the =pud-worlds= variable, as in: For instance, you could set up a call to =setopt= or customize the =pud-worlds= variable, as in:
#+BEGIN_SRC emacs-lisp :tangle no :eval no
(use-package pud
:custom
(pud-worlds
'(["Remote Moss-n-Puddles" 'ssh "howardabrams.com" 4000 "bobby"]
; ↑ No password? Should be in .authinfo.gpg
["Local Root" 'telnet "localhost" 4000 "suzy" "some-pass"]
; ↑ This has the password in your custom settings.
; ↓ Password from authinfo, special connection string:
["Local User" 'telnet "localhost" 4000 "rick" nil "login %s %s"])))
#+END_SRC
Or set up the customization in the =init.el= file:
#+BEGIN_SRC emacs-lisp :tangle no :eval no #+BEGIN_SRC emacs-lisp :tangle no :eval no
(setopt pud-worlds (setopt pud-worlds
'(["Moss-n-Puddles" ssh "howardabrams.com" 4004 "howard" "" "connect %s %s"] '(["Moss-n-Puddles" ssh "howardabrams.com" 4004 "howard" "" "\\nconnect %s %s\\n"]
["Moss-n-Puddles" ssh "howardabrams.com" 4004 "rick" "" "connect %s %s"] ["Moss-n-Puddles" ssh "howardabrams.com" 4004 "rick" "" "\\nconnect %s %s\\n"]
["Moss-n-Puddles" ssh "howardabrams.com" 4004 "darol" "" "\\nconnect %s %s\\n"]
["Local-Moss" telnet "localhost" 4000 "howard" "" ""] ["Local-Moss" telnet "localhost" 4000 "howard" "" ""]
["Local-Moss" telnet "localhost" 4000 "rick" "" ""])) ["Local-Moss" telnet "localhost" 4000 "rick" "" ""]))
#+END_SRC #+END_SRC
@ -174,8 +191,9 @@ The following functions are accessibility functions to the world entry.
world)) world))
(defun pud-world-network (world) (defun pud-world-network (world)
"Return the network details for WORLD as a cons cell (HOST . PORT)." "Return the network details for WORLD as a list.
(list (aref world 2) (format "%s" (aref world 3)))) [Connect-Type Host Port]."
(list (aref world 1) (aref world 2) (format "%s" (aref world 3))))
(defun pud-world-creds (world) (defun pud-world-creds (world)
"Return the username and password from WORLD. "Return the username and password from WORLD.
@ -197,14 +215,14 @@ And some basic functions I should expand.
#+BEGIN_SRC emacs-lisp :tangle no #+BEGIN_SRC emacs-lisp :tangle no
(ert-deftest pud-world-name-test () (ert-deftest pud-world-name-test ()
(should (string-equal (pud-world-name "foobar") "foobar")) (should (string-equal (pud-world-name "foobar") "foobar"))
(should (string-equal (pud-world-name ["foobar" "localhost" "4000"]) "foobar")) (should (string-equal (pud-world-name ["foobar" 'telnet "localhost" "4000"]) "foobar"))
(should (string-equal (pud-world-name ["foobar" "localhost" "4000" ""]) "foobar")) (should (string-equal (pud-world-name ["foobar" 'telnet "localhost" "4000" nil]) "foobar"))
(should (string-equal (pud-world-name ["foobar" "localhost" "4000" nil]) "foobar")) (should (string-equal (pud-world-name ["foobar" 'telnet "localhost" "4000" ""]) "foobar"))
(should (string-equal (pud-world-name ["foobar" "localhost" "4000" "guest" "guest"]) "guest@foobar"))) (should (string-equal (pud-world-name ["foobar" 'telnet "localhost" "4000" "guest" "guest"]) "guest@foobar")))
(ert-deftest pud-world-network-test () (ert-deftest pud-world-network-test ()
(should (equal (pud-world-network ["foobar" telnet "overthere" "4000" "guest" "guest"]) '("overthere" "4000"))) (should (equal (pud-world-network ["foobar" telnet "overthere" "4000" "guest" "guest"]) '(telnet "overthere" "4000")))
(should (equal (pud-world-network ["foobar" ssh "overthere" 4000 "guest" "guest"]) '("overthere" "4000")))) (should (equal (pud-world-network ["foobar" ssh "overthere" 4000 "guest" "guest"]) '(ssh "overthere" "4000"))))
(ert-deftest pud-world-creds-test () (ert-deftest pud-world-creds-test ()
;; Test with no match in authinfo! ;; Test with no match in authinfo!
@ -226,6 +244,12 @@ Using Comint, and hoping to have the ANSI colors displayed.
(load "ansi-color" t) (load "ansi-color" t)
#+END_SRC #+END_SRC
Get full colors using the [[https://github.com/atomontage/xterm-color][xterm-color]] project:
#+BEGIN_SRC emacs-lisp
(use-package xterm-color)
#+END_SRC
Im going to use good ol fashion =telnet= for the connection: Im going to use good ol fashion =telnet= for the connection:
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
@ -253,8 +277,9 @@ Command string to use, given a =world= with a connection type:
(defun pud-cli-command (world) (defun pud-cli-command (world)
"Return a command string to pass to the shell. "Return a command string to pass to the shell.
The WORLD is a vector with the hostname, see `pud-worlds'." The WORLD is a vector with the hostname, see `pud-worlds'."
(seq-let (host port) (pud-world-network world) (seq-let (connection-type host port) (pud-world-network world)
(cl-case (aref world 1) (message "Dealing with: %s %s %s" connection-type host port)
(cl-case connection-type
(telnet (append (cons pud-telnet-path pud-cli-arguments) (telnet (append (cons pud-telnet-path pud-cli-arguments)
(list host port))) (list host port)))
(ssh (append (cons pud-ssh-path pud-cli-arguments) (ssh (append (cons pud-ssh-path pud-cli-arguments)
@ -318,6 +343,7 @@ The main entry point to the program is the =pud-run= function:
(process (get-buffer-process buffer))) (process (get-buffer-process buffer)))
;; if the process is dead then re-create the process and reset the ;; if the process is dead then re-create the process and reset the
;; mode. ;; mode.
(message "Gonna %s with %s" (car pud-cli) (cdr pud-cli))
(unless proc-alive (unless proc-alive
(with-current-buffer buffer (with-current-buffer buffer
(apply 'make-comint-in-buffer "Pud" buffer (car pud-cli) nil (cdr pud-cli)) (apply 'make-comint-in-buffer "Pud" buffer (car pud-cli) nil (cdr pud-cli))
@ -407,7 +433,14 @@ Note that =comint-process-echoes=, depending on the mode and the circumstances,
;; (set (make-local-variable 'paragraph-separate) "\\'") ;; (set (make-local-variable 'paragraph-separate) "\\'")
;; (set (make-local-variable 'font-lock-defaults) '(pud-font-lock-keywords t)) ;; (set (make-local-variable 'font-lock-defaults) '(pud-font-lock-keywords t))
;; (set (make-local-variable 'paragraph-start) pud-prompt-regexp) ;; (set (make-local-variable 'paragraph-start) pud-prompt-regexp)
)
;; Get the xterm colorization on:
(require 'xterm-color)
(font-lock-mode -1)
;; Prevent font-locking from being re-enabled in this buffer
(make-local-variable 'font-lock-function)
(setq font-lock-function (lambda (_) nil))
(add-hook 'comint-preoutput-filter-functions 'xterm-color-filter nil t))
(add-hook 'pud-mode-hook 'pud--initialize) (add-hook 'pud-mode-hook 'pud--initialize)

View file

@ -0,0 +1,7 @@
# -*- mode: snippet -*-
# name: Evennia
# key: <ev
# --
#+BEGIN_SRC evennia
$0
#+END_SRC

6
snippets/tcl-mode/send Normal file
View file

@ -0,0 +1,6 @@
# -*- mode: snippet -*-
# name: send
# key: send
# --
send "${1}\n"
expectit "$0"

View file

@ -198,6 +198,19 @@ The [[https://github.com/zsh-users/zsh-syntax-highlighting][ZShell Syntax Highli
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
#+END_SRC #+END_SRC
** Language Support
Anything special for particular languages.
*** Python
Not overly impressed, for to get =pyenv= to work, we need to add this code:
#+BEGIN_SRC zsh
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
#+END_SRC
** Plugins ** Plugins
Configure the plugins, making sure to not use =git=, as the aliases are a pain to remember when I already have a superior Git interface in Emacs. Configure the plugins, making sure to not use =git=, as the aliases are a pain to remember when I already have a superior Git interface in Emacs.
@ -209,12 +222,13 @@ Configure the plugins, making sure to not use =git=, as the aliases are a pain t
- =tab= :: To open a new terminal tab - =tab= :: To open a new terminal tab
- =cdf= :: To open a directory in the Finder, meh. Why not change this to open it in =dired= in Emacs? - =cdf= :: To open a directory in the Finder, meh. Why not change this to open it in =dired= in Emacs?
- =quick-look= :: To view a file - =quick-look= :: To view a file
- [[https://github.com/ohmyzsh/ohmyzsh/blob/master/plugins/pyenv/README.md][pyenv]] :: Call the =pyenv init= and whatnot.
- [[https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/zbell][zbell]] :: To beep when a long running command has completed. Similar to my =beep= command. - [[https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/zbell][zbell]] :: To beep when a long running command has completed. Similar to my =beep= command.
To have a plugin /install/, add its name to the =plugins= array variable /before/ we =source= the OMZ script: To have a plugin /install/, add its name to the =plugins= array variable /before/ we =source= the OMZ script:
#+begin_SRC zsh #+begin_SRC zsh
plugins=(colorize direnv gnu-utils iterm2 macos zbell zsh-syntax-highlighting) plugins=(colorize direnv gnu-utils iterm2 macos pyenv virtualenv zbell zsh-syntax-highlighting)
#+END_SRC #+END_SRC
Notice the =iterm2= plugin as well as the =macos= plugins that would be nice to figure out how to make them optionally added (although I believe they check themselves). Notice the =iterm2= plugin as well as the =macos= plugins that would be nice to figure out how to make them optionally added (although I believe they check themselves).
@ -263,7 +277,7 @@ I keep the prompt simple since all of the /gunk/ we typically put in a prompt is
* iTerm2 * iTerm2
On Mac systems, I like the [[https://www.iterm2.com/][iTerm2 application]], and we can enable [[https://iterm2.com/documentation-shell-integration.html][shell integration]], either via the old school way, or just rely on [[https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/iterm2][the /plugin/ ]]above: On Mac systems, I like the [[https://www.iterm2.com/][iTerm2 application]], and we can enable [[https://iterm2.com/documentation-shell-integration.html][shell integration]], either via the old school way, or just rely on [[https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/iterm2][the /plugin/ ]]above:
#+BEGIN_SRC zsh :tangle no #+BEGIN_SRC zsh
test -e "${HOME}/.iterm2_shell_integration.zsh" && source "${HOME}/.iterm2_shell_integration.zsh" test -e "${HOME}/.iterm2_shell_integration.zsh" && source "${HOME}/.iterm2_shell_integration.zsh"
#+END_SRC #+END_SRC
@ -273,18 +287,31 @@ Also, while use the =title= command to change the Terminals title bar, don
DISABLE_AUTO_TITLE="true" DISABLE_AUTO_TITLE="true"
#+END_SRC #+END_SRC
Favorite feature is the Status Bar at the bottom of the screen that shows the Git branch, current working directory, etc. This allows my prompt to be much shorter. What other information I want has changed over the years, but I define this information with this function: Favorite feature is the [[https://iterm2.com/documentation-status-bar.html][Status Bar]] at the bottom of the screen that shows the Git branch, current working directory, etc. This allows my prompt to be much shorter. What other information I want has changed over the years, but I define this information with this function:
Currently, I show the currently defined Kube namespace. Currently, I show the currently defined Kube namespace.
#+BEGIN_SRC zsh #+BEGIN_SRC zsh
function iterm2_print_user_vars() { function iterm2_print_user_vars() {
iterm2_set_user_var kubecontext $($ yq '.users[0].name' ~/.kube/config):$(kubectl config view --minify --output 'jsonpath={..namespace}') # iterm2_set_user_var kubecontext $($ yq '.users[0].name' ~/.kube/config):$(kubectl config view --minify --output 'jsonpath={..namespace}')
# Correct version: # Correct version:
# iterm2_set_user_var kubecontext $(kubectl config current-context):$(kubectl config view --minify --output 'jsonpath={..namespace}') # iterm2_set_user_var kubecontext $(kubectl config current-context):$(kubectl config view --minify --output 'jsonpath={..namespace}')
# Faster version: # Faster version:
# iterm2_set_user_var kubecontext $(awk '/^current-context:/{print $2;exit;}' <~/.kube/config) iterm2_set_user_var kubecontext $(awk '/^current-context:/{print $2;exit;}' <~/.kube/config)
iterm2_set_user_var pycontext "$(pyenv version-name):$(echo $VIRTUAL_ENV | sed 's/.*.venv\///')"
}
#+END_SRC
Add the following:
#+BEGIN_SRC zsh
function pycontext {
local version venvstr
version=$(pyenv version-name)
venvstr=$(echo $VIRTUAL_ENV | sed 's/.*.venv\///')
echo "🐍 $version:$venvstr"
} }
#+END_SRC #+END_SRC