This is still the header! Main site

Not Using Terminals Pt. 4: Quick Script Creation

2024/09/15

In our previous episode, we made a case for creating an excessive number of scripts, as a replacement for shell history + typing in commands on the fly. We even added a script that lets you save previous invocations as a script. But then... trivial inconveniences might still prevent you from doing this, reverting to "just typing in this one command".

What we need is... making this even more accessible. By which we mean... you shouldn't think about it.

Shell history is something that you can access without much thinking. Accessing your "scripts" directory can be the same! E.g. you can just do something like


(defvar ssafar-scripts-path "h:\\bin")

(defun ssafar-open-scripts-dir ()
  (interactive)
  (find-file ssafar-scripts-path))

(global-set-key (kbd "") 'ssafar-open-scripts-dir)
          

With this, wherever you are, F2 will open up your scripts directory in dired.

Of course, there should be one default "scripts" directory. Doesn't even need to be on the path, but it should have an easy to remember name (e.g. ~/bin). The important part is that figuring out where to put this script should take about the same amount of mental effort as deciding which bash history file to save your latest command to (i.e. "none"; you don't even choose, there is just the one, period).

But then... you'd still need to... pick unique names for them...?

Well, we don't have to. Take the following snippet:


(defun ssafar-new-bash-script (name skip-date-p)
  (interactive "MName for new script: \nP") ;; takes 2 args: a name and a universal arg to switch whether we'd want a date on
  (let* ((script-name  ;; looks like "something_you_typed_in_20240915"
          (format "%s%s"
                  name
                  (if skip-date-p "" (format-time-string "_%Y%m%d"))))
         (script-full-path  ;; turn it into a full absolute path
          (format "%s%s" (file-name-as-directory ssafar-scripts-path)
                  script-name)))   ;;  file-name-as-directory adds a trailing / or \ if needed
    (find-file script-full-path) ;; open the new script
    (shell-script-mode)  ;; shell script syntax highlighting
    (insert "#!/bin/bash\n\n")  ;; some template text
    (insert "set -e\n\n")
    (save-buffer)  ;; ... so that we can run it later
    (compilation-start script-full-path)))   ;; run it!
          

You can bind this to... e.g. the key "N" in dired:


(define-key dired-mode-map (kbd "N") 'ssafar-new-bash-script)
          
... so whenever you want a new script, all you have to do is

This will:

More ideas

Doing this for bash scrips merely brings up pretty close to how easy it is to throw in command line commands. Do the same with Python scripts: suddenly, the difference between "this is just a command on the command line" and "this is a full-blown Python program" ends up being a lot smaller.

For additional fun: at the first sign of shell scripting getting ugly, throw the entire thing into an LLM, "please turn this into Python", and continue from there, with a new script.