3 Create my snippet expansions for Alfred.
13 def read ( name : str ) -> str :
15 Return the contents of text file in the `expansions` folder.
17 with open ( os . path . join ( "expansions" , name )) as infile :
23 "!bq" : "<blockquote> {clipboard} </blockquote>" ,
25 # =========================
26 # Get the current date/time
27 # =========================
29 # pretty, e.g. 9 April 2024
30 ";dp" : "{isodate:d MMMM yyyy}" ,
32 # short, e.g. 2024-04-09
33 ";ds" : "{isodate:yyyy-MM-dd}" ,
35 # e.g. 2024-04-09 10:49:12 +01:00
36 ";dd" : "{isodate:yyyy-MM-dd HH:mm:ss xxx}" ,
39 # I use this for timestamped entries in my Obsidian journal
40 ";dt" : r "\[{isodate:HH:mm}] " ,
42 # e.g. 2025-02-09T09:13:58Z
43 # I use this for timestamped entries in JavaScript/JSON files
44 ";dj" : " {isodatetime} " ,
46 # =========================
47 # English words and phrases
48 # =========================
50 "a11y" : "accessibility" ,
51 "A11y" : "Accessibility" ,
56 "afaict" : "as far as I can tell" ,
57 " atm" : " at the moment" ,
63 "bdies" : "boundaries" ,
64 "Bdies" : "Boundaries" ,
68 " cts" : " continuous" ,
70 "Das Ubermensch" : "Das Übermensch" ,
74 "dept." : "department" ,
75 "distn" : "distribution" ,
76 "digipres" : "digital preservation" ,
77 "Digipres" : "Digital preservation" ,
87 "gov't" : "government" ,
90 "i14n" : "intersectional" ,
91 "i18n" : "internationalisation" ,
92 " iff" : " if and only if" ,
93 "ina11e" : "inaccessible" ,
94 "indpt" : "independent" ,
95 "intl." : "international" ,
96 "iptic" : "in particular" ,
97 "Iptic" : "In particular" ,
98 "l12n" : "localisation" ,
100 "mgmt" : "management" ,
101 "Mgmt" : "Management" ,
106 "nbhd" : "neighbourhood" ,
108 " o/w" : " otherwise" ,
109 " O/w" : " Otherwise" ,
111 " ptic" : " particular" ,
112 "rec'd" : "recommended" ,
120 "stdlib" : "standard library" ,
124 "w/b" : "week beginning" ,
125 "w/e" : "week ending" ,
127 "y'day" : "yesterday" ,
129 # =============================
130 # Fix my common typing mistakes
131 # =============================
133 "EVentbridge" : "EventBridge" ,
143 "Airdrop" : "AirDrop" ,
144 "Anais Mitchell" : "Anaïs Mitchell" ,
145 "B'ham" : "Birmingham" ,
146 "BackBlaze" : "Backblaze" ,
148 "Borrowbox" : "BorrowBox" ,
150 "China Mieville" : "China Miéville" ,
151 "Cloudwatch" : "CloudWatch" ,
153 "El Otro Periodico" : "El Otro Periódico" ,
154 "Elasticache" : "ElastiCache" ,
156 "Eventbridge" : "EventBridge" ,
157 "Facetime" : "FaceTime" ,
158 "FastMail" : "Fastmail" ,
159 "Gitbook" : "GitBook" ,
160 "Hashicorp" : "HashiCorp" ,
161 "Maciej Ceglowski" : "Maciej Cegłowski" ,
163 "Phylopic" : "PhyloPic" ,
164 "Postgresql" : "PostgreSQL" ,
165 "Powerpoint" : "PowerPoint" ,
166 "Raphaelle" : "Raphaëlle" ,
167 "Redmonk" : "RedMonk" ,
168 "Regents Canal" : "Regent’s Canal" ,
169 "Rubocop" : "RuboCop" ,
173 "Sharepoint" : "SharePoint" ,
175 "Smugmug" : "SmugMug" ,
176 "Spitlip" : "SpitLip" ,
178 "Textexpander" : "TextExpander" ,
180 "Whatsapp" : "WhatsApp" ,
181 "WikiData" : "Wikidata" ,
182 "Wireguard" : "WireGuard" ,
183 "Wordpress" : "WordPress" ,
184 "Youtube" : "YouTube" ,
190 # =================================
191 # Symbols and other bits of Unicode
192 # =================================
220 ";zwsp" : " \u200b " , # zero-width space
222 # This snippet draws a basic tree with Unicode characters, which
223 # I can copy/paste to build a more complex tree by hand.
224 "!tree" : read ( "tree.txt" ),
229 "@aa" : "@alexwlchan.net" ,
230 ";ee" : "alex@alexwlchan.net" ,
232 ";ale" : "alexwlchan" ,
234 ";so" : "Signed-off-by: Alex Chan <alexc@tailscale.com>" ,
237 ";san" : "social.alexwlchan.net" ,
239 # ====================
240 # Programming snippets
241 # ====================
242 "!bash" : "#!/usr/bin/env bash \n\n set -o errexit \n set -o nounset \n " ,
243 "!osa" : "#!/usr/bin/env osascript \n " ,
244 "!py" : "#!/usr/bin/env python3 \n\n " ,
245 "!rb" : "#!/usr/bin/env ruby \n " ,
246 "!swift" : "#!/usr/bin/env swift \n " ,
248 "!rect" : '<rect width="500" height="250" fill="yellow"/>' ,
249 "!svg" : read ( "template.svg" ),
250 "!cogsvg" : read ( "cog_template.svg" ),
252 "!before" : read ( "before_and_after.html" ),
254 "!mit" : read ( "mit_license.txt" ),
257 # See https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors
258 ";co" : "Co-authored-by:" ,
260 ";sc" : "Updates #cleanup \n\n Signed-off-by: Alex Chan <alexc@tailscale.com>" ,
262 # ===================================
263 # Python-related programming snippets
264 # ===================================
265 "!dt" : "from datetime import datetime, timezone \n " ,
266 "!j" : "import json \n " ,
267 "!pp" : "from pprint import pprint; pprint( {cursor} )" ,
269 "@param" : "@pytest.mark.parametrize( {cursor} )" ,
271 "!flapi" : read ( "flapi.py" ),
273 "py!aws" : read ( "get_boto3_session.py" ),
274 "py!dy" : read ( "list_dynamodb_rows.py" ),
275 "py!h" : read ( "create_hash.py" ),
276 "py!de" : read ( "datetime_encoder.py" ),
277 "py!pth" : read ( "get_file_paths.py" ),
278 "py!pd" : read ( "get_directories.py" ),
279 "py!sec" : read ( "get_secrets_manager_secret.py" ),
280 "py!s3" : read ( "list_s3_objects.py" ),
281 "py!ej" : read ( "edit_javascript.py" ),
283 # I can never remember the order of args to this function,
284 # so when I start typing it, add a comment to help me out.
285 "datetime.datetime.strp" : (
286 "datetime.datetime.strptime( {cursor} ) "
287 "# date_string, format" ),
292 ";nd" : read ( "note_header.txt" ),
297 "porque?" : "¿Por qué no los dos?" ,
302 def add_snippet ( zf : zipfile . ZipFile , shortcut : str , expansion : str ) -> None :
304 Add a single snippet to a snippets bundle.
307 h . update ( shortcut . encode ( "utf8" ))
308 h . update ( expansion . encode ( "utf8" ))
310 snippet_id = uuid . UUID ( hex = h . hexdigest ())
314 "snippet" : expansion ,
315 "uid" : str ( snippet_id ),
321 zf . writestr ( f " { snippet_id } .json" , data = json . dumps ( snippet_data ))
324 if __name__ == "__main__" :
325 with zipfile . ZipFile ( "Alex’s snippets.alfredsnippets" , "w" ) as zf :
326 zf . write ( "info.plist" )
328 for shortcut , expansion in SNIPPETS . items ():
329 add_snippet ( zf , shortcut , expansion )