Compare commits
4 commits
e96dc58c87
...
bd69943337
Author | SHA1 | Date | |
---|---|---|---|
|
bd69943337 | ||
|
c7049e12e0 | ||
|
6da8591a1d | ||
|
b171fbc3bf |
6 changed files with 168 additions and 22 deletions
|
@ -179,8 +179,17 @@ I’ve often called =imenu= to easily jump to a function definition in a file (o
|
|||
*** Remote Files
|
||||
To speed up TRAMP access, let’s disabled lock files, you know, the ones that have the =#= surrounding characters:
|
||||
#+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
|
||||
|
||||
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]]?
|
||||
|
||||
During remote access, TRAMP can slow down performing Git operations. Let’s turn that off as well:
|
||||
|
|
|
@ -44,6 +44,7 @@ While Emacs supplies a Python editing environment, we’ll still use =use-packag
|
|||
(flycheck-add-next-checker 'python-pylint 'python-pycompile 'append))
|
||||
#+end_src
|
||||
|
||||
|
||||
** 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=:
|
||||
|
||||
|
@ -136,11 +137,64 @@ Next, after reading David Vujic’s [[https://davidvujic.blogspot.com/2025/03/ar
|
|||
#+END_SRC
|
||||
|
||||
** 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 project’s 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
|
||||
pip install pyenv
|
||||
#+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]]:
|
||||
#+begin_src conf
|
||||
use python 3.7.1
|
||||
|
@ -257,6 +311,16 @@ Let’s expand our =major-mode-hydra= with some extras:
|
|||
("D" elpy-doc "Docs Symbol")))))
|
||||
#+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
|
||||
** 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=):
|
||||
|
|
61
pud.org
61
pud.org
|
@ -2,7 +2,7 @@
|
|||
#+author: Howard X. Abrams
|
||||
#+date: 2025-01-18
|
||||
#+filetags: emacs hamacs
|
||||
#+lastmod: [2025-08-05 Tue]
|
||||
#+lastmod: [2025-08-23 Sat]
|
||||
|
||||
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:
|
||||
|
||||
#+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
|
||||
(setopt pud-worlds
|
||||
'(["Moss-n-Puddles" ssh "howardabrams.com" 4004 "howard" "" "connect %s %s"]
|
||||
["Moss-n-Puddles" ssh "howardabrams.com" 4004 "rick" "" "connect %s %s"]
|
||||
'(["Moss-n-Puddles" ssh "howardabrams.com" 4004 "howard" "" "\\nconnect %s %s\\n"]
|
||||
["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 "rick" "" ""]))
|
||||
#+END_SRC
|
||||
|
@ -174,8 +191,9 @@ The following functions are accessibility functions to the world entry.
|
|||
world))
|
||||
|
||||
(defun pud-world-network (world)
|
||||
"Return the network details for WORLD as a cons cell (HOST . PORT)."
|
||||
(list (aref world 2) (format "%s" (aref world 3))))
|
||||
"Return the network details for WORLD as a list.
|
||||
[Connect-Type Host Port]."
|
||||
(list (aref world 1) (aref world 2) (format "%s" (aref world 3))))
|
||||
|
||||
(defun pud-world-creds (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
|
||||
(ert-deftest pud-world-name-test ()
|
||||
(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" "localhost" "4000" ""]) "foobar"))
|
||||
(should (string-equal (pud-world-name ["foobar" "localhost" "4000" nil]) "foobar"))
|
||||
(should (string-equal (pud-world-name ["foobar" "localhost" "4000" "guest" "guest"]) "guest@foobar")))
|
||||
(should (string-equal (pud-world-name ["foobar" 'telnet "localhost" "4000"]) "foobar"))
|
||||
(should (string-equal (pud-world-name ["foobar" 'telnet "localhost" "4000" nil]) "foobar"))
|
||||
(should (string-equal (pud-world-name ["foobar" 'telnet "localhost" "4000" ""]) "foobar"))
|
||||
(should (string-equal (pud-world-name ["foobar" 'telnet "localhost" "4000" "guest" "guest"]) "guest@foobar")))
|
||||
|
||||
(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" ssh "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"]) '(ssh "overthere" "4000"))))
|
||||
|
||||
(ert-deftest pud-world-creds-test ()
|
||||
;; Test with no match in authinfo!
|
||||
|
@ -226,6 +244,12 @@ Using Comint, and hoping to have the ANSI colors displayed.
|
|||
(load "ansi-color" t)
|
||||
#+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
|
||||
|
||||
I’m going to use good ‘ol fashion =telnet= for the connection:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
|
@ -253,8 +277,9 @@ Command string to use, given a =world= with a connection type:
|
|||
(defun pud-cli-command (world)
|
||||
"Return a command string to pass to the shell.
|
||||
The WORLD is a vector with the hostname, see `pud-worlds'."
|
||||
(seq-let (host port) (pud-world-network world)
|
||||
(cl-case (aref world 1)
|
||||
(seq-let (connection-type host port) (pud-world-network world)
|
||||
(message "Dealing with: %s %s %s" connection-type host port)
|
||||
(cl-case connection-type
|
||||
(telnet (append (cons pud-telnet-path pud-cli-arguments)
|
||||
(list host port)))
|
||||
(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)))
|
||||
;; if the process is dead then re-create the process and reset the
|
||||
;; mode.
|
||||
(message "Gonna %s with %s" (car pud-cli) (cdr pud-cli))
|
||||
(unless proc-alive
|
||||
(with-current-buffer buffer
|
||||
(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 'font-lock-defaults) '(pud-font-lock-keywords t))
|
||||
;; (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)
|
||||
|
||||
|
|
7
snippets/org-mode/evennia
Normal file
7
snippets/org-mode/evennia
Normal file
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: Evennia
|
||||
# key: <ev
|
||||
# --
|
||||
#+BEGIN_SRC evennia
|
||||
$0
|
||||
#+END_SRC
|
6
snippets/tcl-mode/send
Normal file
6
snippets/tcl-mode/send
Normal file
|
@ -0,0 +1,6 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: send
|
||||
# key: send
|
||||
# --
|
||||
send "${1}\n"
|
||||
expectit "$0"
|
37
zshell.org
37
zshell.org
|
@ -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
|
||||
#+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
|
||||
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
|
||||
- =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
|
||||
- [[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.
|
||||
|
||||
To have a plugin /install/, add its name to the =plugins= array variable /before/ we =source= the OMZ script:
|
||||
|
||||
#+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
|
||||
|
||||
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
|
||||
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"
|
||||
#+END_SRC
|
||||
|
||||
|
@ -273,18 +287,31 @@ Also, while use the =title= command to change the Terminal’s title bar, don’
|
|||
DISABLE_AUTO_TITLE="true"
|
||||
#+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.
|
||||
|
||||
#+BEGIN_SRC zsh
|
||||
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:
|
||||
# iterm2_set_user_var kubecontext $(kubectl config current-context):$(kubectl config view --minify --output 'jsonpath={..namespace}')
|
||||
# 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
|
||||
|
||||
|
|
Loading…
Reference in a new issue