Skip to content

Instantly share code, notes, and snippets.

View samkcarlile's full-sized avatar
👽

Sam Carlile samkcarlile

👽
View GitHub Profile
@samkcarlile
samkcarlile / git_functions.zsh
Created September 6, 2025 16:23
useful git zsh functions
unalias gbl
function gbl() {
# todo: colorize branches by last commit
# todo: show 10 by default
gb --sort=committerdate |
tail -n 5 |
gum filter --limit=1 --header="Type to checkout a branch" --placeholder="" |
xargs -I _ git checkout _ || echo Current branch already checked out.
}
@samkcarlile
samkcarlile / typedObjectPathValue.ts
Created August 29, 2025 06:01
Typed Object Path Value
type ObjectPathValue<T, U extends readonly string[]> = U extends [
infer FirstProp extends keyof T,
...infer RestProps extends readonly string[]
]
? ObjectPathValue<T[FirstProp], RestProps>
: T;
function $get<T extends object, U extends readonly string[]>(
target: T,
path: [...U]
// tree node type
type Node = {
  id: number;
  children: () => Promise<Node[]>
}

// results array
const results: Node[] = [];
@samkcarlile
samkcarlile / tokenize.ts
Last active February 10, 2023 21:54
TypeScript Tokenizer
type TokenSpec<T = any> = { match: RegExp; value: (s: string) => T };
type TokenConfig = Record<string, RegExp | TokenSpec>;
type TokenTypes<T extends TokenConfig> = {
[Type in keyof T]: T[Type] extends TokenSpec
? { type: Type; value: ReturnType<T[Type]['value']> }
: { type: Type; value: string };
}[keyof T];
/**
* @param str The input string
@samkcarlile
samkcarlile / range.ts
Created May 4, 2022 16:16
The missing `range` iterator
export function range(start: number, stop = start, step = 1) {
start = stop === start ? 0 : start;
const end = stop === start ? start : stop;
return {
*[Symbol.iterator]() {
for (let i = start; i < end; i += step) yield i;
},
};
}
@samkcarlile
samkcarlile / join.ts
Last active May 3, 2022 03:07
Weird `join` implementation
const dogs = [
{ name: 'Fido', favorites: ['sam', 'mark', 'bob'] },
{ name: 'Happy', favorites: ['mark'] },
{ name: 'Buddy', favorites: ['bob'] },
{ name: 'Oscar', favorites: ['mark', 'sam', 'bob'] },
];
const friends = [
{ name: 'sam', age: 22, toes: 5 },
{ name: 'mark', age: 37, toes: 9 },
@samkcarlile
samkcarlile / render.ts
Created February 23, 2022 02:02
templating engine
function render(template: string, data: any, brackets = ['{{', '}}']) {
const output: string[] = [];
const [left, right] =
brackets.length > 1 ? brackets : [...brackets, ...brackets];
let pos = 0;
while (pos < template.length) {
const start = template.indexOf(left, pos);
if (start < 0) break;
@samkcarlile
samkcarlile / .zshrc
Created October 27, 2021 16:06
git checkout with fzf
function gcz() {
if [[ -z $1 ]]; then
git checkout $(gb | fzf | tr -d ' *')
else
git checkout $(gb | fzf -1 -q $1 | tr -d ' *')
fi
}
@samkcarlile
samkcarlile / csv-to-json.js
Last active July 21, 2021 17:47
Parsing a multi-line CSV
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const tweetCSVFile = path.resolve(__dirname, '../all_tweets_classified.csv');
const outFile = path.resolve(__dirname, '../all_tweets_classified.json');
const [header, rows] = parseCSV(tweetCSVFile);
const jsonData = csvToJson([header, rows], {
msg_id: String,
@samkcarlile
samkcarlile / Setting up ESLint + Airbnb + Prettier in VSCode.md
Last active September 2, 2020 13:42
My attempt at clarifying the steps to getting up and running with ESLint and Airbnb's configuration inside of VSCode.

Setting up ESLint + Airbnb + Prettier in VSCode

(Step #1) – VSCode extensions & settings

  • Install the ESLint extension in VSCode.
    • This actually parses the Javascript you write and applies syntax and semantic rules.
  • Install the Prettier code formatter extension in VSCode.
    • All this does is format the code you've written to look nice. No syntax checking or parsing of your Javascript. If you don't install this, you'll still get all the benefits of linting and VSCode's built-in formatter.