Skip to content

Instantly share code, notes, and snippets.

@pyrtsa
pyrtsa / version.bash
Last active March 23, 2023 06:47
Xcode: Set version and build number from Git
#!/bin/bash
# Xcode: Set version and build number from Git
# --------------------------------------------
#
# This script sets the version number `CFBundleShortVersionString` to one of
#
# - `1.2.3` -- for the tagged commit `v1.2.3` or a hyphen-separated prerelease,
# e.g. `v1.2.3-alpha`, `v1.2.3-alpha.2`, `v1.2.3-beta`, `v1.2.3-rc`.
# - `1.2.3-7-gabc1234` -- at commit `abc1234`, 7 commits after `v1.2.3`,
# - `1.2.3-7-gabc1234-dirty` -- when there are uncommitted changes, or
@pyrtsa
pyrtsa / .prompt-time
Last active February 12, 2023 05:12
Make Bash report the start times all commands, and total durations of long-running ones.
export _ps1_timer
function _ps1_timer_start {
# echo START
_ps1_timer=${_ps1_timer:-`gdate +%s%N 2> /dev/null || date +%s%N`};
}
function _ps1_timer_stop {
# echo STOP
if [ -z "$_ps1_timer" ]; then
@pyrtsa
pyrtsa / .ghci
Created October 19, 2012 07:28
Color your ghci prompt
-- Print the imported modules in green, then ">>> " on the following line.
:set prompt "\SOH\ESC[32m\STX%s\SOH\ESC[0m\STX\n\SOH\ESC[32;1m\STX>>>\SOH\ESC[0m\STX "
-- (Disclaimer: ghci doesn't currently support configuring the prompt on
-- continuation lines for multiline inputs, so you'll get something like
-- "Prelude|" instead of something convenient like a green "... ". Patches
-- welcome, I guess!)
@pyrtsa
pyrtsa / .gitconfig
Created October 31, 2011 10:41
A few `git log` commands where things are nicely aligned
[alias]
l50 = "!f () { git log --abbrev-commit --date=short --pretty=format:'%h%x00%cd%x00%s%x00%an%x00%d' $@ | gawk -F '\\0' '{ printf \"\\033[31m%s\\033[0m \\033[32m%s\\033[0m %-50s \\033[30;1m%s\\033[0m\\033[33m%s\\n\", $1, $2, gensub(/(.{49}).{2,}/, \"\\\\1…\",\"g\",$3), $4, $5 }' | less -R; }; f"
l80 = "!f () { git log --abbrev-commit --date=short --pretty=format:'%h%x00%cd%x00%s%x00%an%x00%d' $@ | gawk -F '\\0' '{ printf \"\\033[31m%s\\033[0m \\033[32m%s\\033[0m %-80s \\033[30;1m%s\\033[0m\\033[33m%s\\n\", $1, $2, gensub(/(.{79}).{2,}/, \"\\\\1…\",\"g\",$3), $4, $5 }' | less -R; }; f"
lg50 = "!f () { git log --graph --color=always --abbrev-commit --date=relative --pretty=format:'%x00%h%x00%s%x00%cd%x00%an%x00%d' $@ | gawk -F '\\0' '{ printf \"%s\\033[31m%s\\033[0m %-50s \\033[32m%14s\\033[0m \\033[30;1m%s\\033[0m\\033[33m%s\\n\", $1, $2, gensub(/(.{49}).{2,}/, \"\\\\1…\",\"g\",$3), $4, $5, $6 }' | less -R; }; f"
lg80 = "!f () { git log --graph --color=always --abbrev-commit --date=re
@pyrtsa
pyrtsa / AnyEquatable.swift
Created May 25, 2016 10:27
AnyEquatable—making Equatable work with class inheritance and existential wrapping ("type erasure")
// Toggle this boolean to compare against stdlib:
#if true // Stdlib version
// Quick hack to avoid changing the AnyEquatable implementation below.
extension Equatable { typealias EqualSelf = Self }
#else // Modified version
protocol Equatable {
@pyrtsa
pyrtsa / any_visitor.cpp
Created June 17, 2012 19:09
Visitor pattern for boost::any in C++11
#include <boost/any.hpp>
#include <unordered_map>
#include <functional>
#include <iostream>
#include <vector>
struct type_info_hash {
std::size_t operator()(std::type_info const & t) const {
return t.hash_code();
}
@pyrtsa
pyrtsa / gist:5151517
Created March 13, 2013 12:09
"Safe" casting in Objective-C using `instancetype`.
#import <Foundation/Foundation.h>
@interface NSObject (Cast)
+ (instancetype)cast:(id)object;
@end
@implementation NSObject (Cast)
+ (instancetype)cast:(id)object
{
return [object isKindOfClass:self] ? object : nil;
@pyrtsa
pyrtsa / exchange.clj
Created December 9, 2013 11:46
Exchange atom value in Clojure. This function seems like a common enough pattern in Clojure it should find its place in the standard library.
(defn exchange!
"Atomically set the value of `atom` to `(apply f @atom args)`,
and return the value of `@atom` just before the assignment.
(See also: `clojure.core/swap!`)"
[atom f & args]
{:pre [(instance? clojure.lang.Atom atom)]}
(loop [oldval @atom]
(if (compare-and-set! atom oldval (apply f oldval args))
oldval
(recur @atom))))
@pyrtsa
pyrtsa / seqables_are_odd.clj
Created April 8, 2014 10:23
Seqables are odd in Clojure. Some functions auto-`seq`, some don't.
(empty? (d/datoms db :aevt :user/id))
;;=> false
(not-empty (d/datoms db :aevt :user/id))
;;=> #<db$datoms$reify__3265 datomic.db$datoms$reify__3265@7939b07>
(seq (d/datoms db :aevt :user/id))
;;=> (#Datum{:e 17592186046081 :a 70 :v "abc" :tx 13194139534976 :added true} ...)
(first (d/datoms db :aevt :user/id))
@pyrtsa
pyrtsa / gist:2275320
Created April 1, 2012 13:27
C++11 metaprogramming
// Here are a few tricks I've used with the trunk versions of clang and libc++
// with C++11 compilation turned on. Some might be obvious, some not, but at
// least they are some kind of improvement over their C++03 counterparts.
//
// Public domain.
// =============================================================================
// 1) Using variadic class templates recursively, like in the definitions for
// "add<T...>" here: