GitHub Stars

GitHub stars posts

1837 posts latest post 2026-05-01
Publishing rhythm
Apr 2026 | 22 posts

The copier answers file is a key component to making your templates re-runnable. Let’s look at the example for my setup.py.

❯ tree ~/.copier-templates/setup.py /home/walkers/.copier-templates/setup.py ├── [[ _copier_conf.answers_file ]].tmpl ├── copier.yml ├── setup.cfg └── setup.py.tmpl 0 directories, 4 files

Inside of my [[ _copier_conf.answers_file ]].tmpl file is this, a message not to muck around with it, and the ansers in yaml form. The first line is just a helper for the blog post.

# ~/.copier-templates/setup.py/\[\[\ _copier_conf.answers_file\ \]\].tmpl # Changes here will be overwritten by Copier; NEVER EDIT MANUALLY [[_copier_answers|to_nice_yaml]]

Inside my copier.yml I have setup my _answers_file to point to a special file. This is because this is not a whole projet template, but one just for a single file.

# copier.yml # ... _answers_file: .setup-py-copier-answers.yml

Once I change the _answers_file I was incredibly stuck

...

Once you have made your sick looking cli apps with rich, eventually you are going to want to add some keybindings to them. Currently Textual, also written by @willmcgugan, does this extremely well. Fair Warning it is in super beta mode and expected to change a bunch. So take it easy with hopping on the train so fast.

Install them from the command line.

pip install textual pip install rich

Import make a .py file and import them in it.

from textual.app import App from textual.widget import Widget from rich.panel import Panel

Make what you have a widget #

If you return your rich renderable out...

...

I’ve been stuck many times looking at a vim buffer with little question marks at the beginning of each line and trying to get rid of them. for so long I didn’t know what they were so trying to get rid of them was impossible.

It turns out they are tabs, and you can get rid of the little leading question marks with this substitution command.

tmux popups can be sized how you like based on the % width of the terminal on creation by using the flags (h, w, x, y) for height, width, and position.

# normal popup tmux popup figlet "Hello" # fullscreen popup tmux popup -h 100% -w 100% figlet "Hello" # 75% centered popup tmux popup -h 100% -w 75% figlet "Hello" # 75% popup on left side tmux popup -h 100% -w 75% -x 0% figlet "Hello"

example running these commands

I was completely stuck for awhile. copier was not replacing my template variables. I found out that adding all these _endops fixed it. Now It will support all of these types of variable wrappers

# copier.yml _templates_suffix: .jinja _envops: block_end_string: "%}" block_start_string: "{%" comment_end_string: "#}" comment_start_string: "{#" keep_trailing_newline: true variable_end_string: "}}" variable_start_string: "{{"

!RTFM: Later I read the docs and realized that copier defaults to using [[ and ]] for its templates unlike other tools like cookiecutter.

I’ve been looking for a templating tool for awhile that works well with single files. My go to templating tool cookiecutter does not work for single files, it needs to put files into a directory underneath of it.

By default copier uses double square brackets for its variables. variables in files, directory_names, or file_names will be substituted for their value once you render them.

# hello-py/hello.py.tmpl print('hello-[[name]]')

note! by default copier will not inject variables into your template-strings unless you use a .tmpl suffix.

Before running copier we need to tell copier what variables to ask for, we do this with a copier.yml file.

...

I just installed a brand new Ubuntu 21.10 Impish Indri, and wanted a kedro project to play with so I did what any good kedroid would do, I went to my command line and ran

pipx run kedro new --starter spaceflights

But what I got back was not what I expected!

Fatal error from pip prevented installation. Full pip output in file: /home/walkers/.local/pipx/logs/cmd_2022-01-01_20.42.16_pip_errors.log Some possibly relevant errors from pip install: ERROR: Could not find a version that satisfies the requirement kedro (from versions: none) ERROR: No matching distribution found for kedro Error installing kedro.

This is weird, why cant I run kedro new with pipx? Lets try pip.

pip install kedro

Same issue.

...

Pluggy makes it so easy to allow users to modify the behavior of a framework without thier specific feature needing to be implemented in the framework itself.

I’ve really been loving the workflow of frameworks built with pluggy. The first one that many python devs have experience with is pytest. I’ve never created a pytest plugin, and honestly at the time I looked into how they were made was a long time ago and it went over my head. I use a data pipelining framework called kedro, and have build many plugins for it.

super easy to do

As long as the framework document the hooks that are available and what it passes to them it’s so easy to make a plugin. Its just importing the hook_impl, making a class with a function that represents one of the hooks, and decorating it.

...

One of the most useful skills you can acquire to make you faster at almost any job that uses a computer is getting good at finding text in your current working diretory and identifying the files that its in. I often use the silver searcher ag or ripgrep rg to find files in large directories quickly. Both have a sane set of defaults that ignore hidden and gitignored files, but getting them to list only the filenames and not the matched was not trivial to me.

I’ve searched throught he help/man pages many times looking for these flags and they always seem to evade me.

Passing the flag -l to ag will get it to list only the filepath, and not the match. Here I gave it a --md as well to only return markdown filetypes. ag supports a number of filetypes in a very similar way.

ag nvim --md -l

rg #

Giving rg the --files-with-matches flag will yield you a similar set of results, giving only the filepaths themselves and not the match statement. Also passing in the -g "*.md" will similarly yield only...

pyenv provides an easy way to install almost any version of python from a large list of distributions. I have simply been using the version of python from the os package manager for awhile, but recently I bumped my home system to Ubuntu 21.10 impish, and it is only 3.9+ while the libraries I needed were only compatable with up to 3.8.

I needed to install an older version of python on ubuntu

I’ve been wanting to check out pyenv for awhile now, but without a burning need to do so.

Based on the Readme it looked like I needed to install using homebrew,so this is what I did, but I later realized that there is a pyenv-installer repo that may have saved me this need.

...

Installing brew on linux proved quite easy and got pyenv running for me within 4 commands.

I had never used homebrew before, honestly I thought it was a mac only thing for years. Today I wanted to try out pyenv, and the reccommended way to install was using homebrew. I am not yet sure if I want either in my normal workflow, so for now I am just going to pop open a new terminal and install homebrew and see how it goes.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> /home/walkers/.zprofile eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"

That was it, now homebrew is working. Starting a new shell and running the command to install pyenv worked.

When I first moved to vim from and ide like vscode or sublime text one of my very first issues was trying to preview my website at localhost:8000. There had always just been a button there to do it in all of my other editors, not vim. There are not many buttons for anything in vim. While there is probably a plugin that can run a webserver for me in vim, it’s not necessary, we just need the command line we are already in.

You will need a way to run another process alongside vim, here are a couple ideas to get you going that are not the focus here.style

Python already exists on most linux systems by default, and most are now on python3. If you are on windows typing python will take you directly to the windows store to install it, or you can also use wsl.

# python3 python -m http.server # running on port 5000 python -m http.server --directory markout 5000

# for the low chance you are on python2 python -m SimpleHTTPServer # running on port 5000 python -m SimpleHTTPServer 5000 python -m SimpleHTTPServer --directory markout 5000 

...

Many command line tools can output a list of files, this is quite powerful. I often want to search for something, then open it from a fuzzy picker. This can be done with fzf in the terminal, but often I am already in vim and I want to open it inside my current session.

how to pass a custom command to telescope

Telescope is the fuzzy file finder I use every day inside of neovim. Its pretty fantastic and easy to extent like this. This first example I am only passing in files from the current working directory by using ls.

:Telescope find_files find_command=ls

This brings up a normal Telescope picker with results from the ls command.

...

vim

Finding hidden files using Telescope as you fuzzy file finder is not too hard, its a single flag passed in. Then it will use whichever file finder it can find [‘fd’, ‘fdfind’, ‘rg –files’, ‘find’, or ‘where’] in that order. These tools each have their own way of handling hidden files, but telescope takes care of that so all you need to do is pass in hidden=true.

I have this keymap set to help me list out all files including hidden files using the pnumonic go edit hidden. I use ge for quite a few different things to take me directly to a specific file or picker.

nnoremap geh <cmd>Telescope find_files hidden=true<cr>

see the implementation telescope finds your files.

vim

Lately I’ve been on a journey to really clean up my dotfiles, and I was completely missing fonts. I noticed jumping into a new vm I had a bunch of broken devicons when using Telescope with the devicons plugins.

This is one of those things that can be a total pain to get right on some systems, and it’s so nice when it’s just there for you pretty much out of the box.

- name: ensure fonts directory file: path: "{{ lookup('env', 'HOME') }}/.fonts" state: directory - name: Hack exists shell: "ls {{ lookup('env', 'HOME') }}/.fonts/Hack*Nerd*Font*Complete*" register: hack_exists ignore_errors: yes - name: Download Hack when: hack_exists is failed ansible.builtin.unarchive: src: https://github.com/ryanoasis/nerd-fonts/releases/download/v2.1.0/Hack.zip dest: "{{ lookup('env', 'HOME') }}/.fonts/" remote_src: yes

...

Part of my neovim setup requires having the black python formatter installed and callable. I install it with pipx so that I don’t have to manage a virtual environment and have it available everywhere. So far this works well for me, if there are ever breaking changes I may need to rethink this.

re-installing a bunch of things that are already installed can be quite a waste and really add up to my ansible run time, so for most of my ansible tasks that install a command like this I have been following this pattern.

- name: check is black installed shell: command -v black register: black_exists ignore_errors: yes - name: install black when: black_exists is failed shell: pipx install black