Skip to content

Instantly share code, notes, and snippets.

@jodersky
jodersky / pickler.scala
Created May 26, 2020 17:57
Simple ujson-based pickler using Dotty typeclass derivation
import scala.deriving._
import scala.compiletime.{erasedValue, summonInline}
// super primitive (but composable via typeclass derivation) JSON reader
trait Reader[A] {
def read(json: ujson.Value): A
}
object Reader {
given Reader[Int] = new Reader[Int] {
@jodersky
jodersky / build.sc
Created March 6, 2021 17:23
Combining scaladoc from multiple sources in mill
// This module isn't really a ScalaModule, but we use it to generate
// consolidated documentation using the Scaladoc tool.
object docs extends ScalaModule {
def scalaVersion = "3.0.0-M3"
def docSource = T.source(millSourcePath)
def moduleDeps = Seq(
...
@jodersky
jodersky / millinit
Last active March 6, 2021 18:23
Initialize a directory with a basic Mill build configuration, using the latest available version of Mill
#!/bin/bash
#
# millinit - fetch mill and initialize a project in a directory
#
# This script will query GitHub to find the newest available version of Mill. It
# will download it and initialize a directory with a basic build configuration.
#
# Usage: millinit <directory>
set -o errexit
@jodersky
jodersky / build.sc
Last active March 31, 2021 18:45
Mill javah
import mill._, scalalib._
trait JavahModule extends JavaModule {
def javah = T {
os.walk(compile().classes.path).filter(_.ext == "class").foreach { path =>
sgjavah.javah(
path.toNIO,
T.dest.toNIO
)
class FunctionExractor(using qctx: Quotes) {
import qctx.reflect._
private case class ToReplace(
outerSymbol: Symbol, // where the container originally comes from, used to collect inputs to the dep
innerTpe: TypeRepr // the original container's partition type
)
/**
def hexify(bytes: Array[Byte]): String = {
val builder = new StringBuilder
for (i <- 0 until bytes.length) {
val b = bytes(i)
val upperNibble = (b >>> 4) & 0x0f
val lowerNibble = b & 0x0f
builder += Character.forDigit(upperNibble, 16)
builder += Character.forDigit(lowerNibble, 16)
}
builder.result()
@jodersky
jodersky / LambdaUtil.scala
Created January 10, 2023 15:52
utilities for serializing and deserializing functions
object LambdaUtil:
import java.lang.invoke.{MethodHandleInfo, SerializedLambda}
def serializeLambda(closure: AnyRef): Array[Byte] =
val writeReplace = closure.getClass.getDeclaredMethod("writeReplace")
writeReplace.setAccessible(true)
val serializable = writeReplace.invoke(closure).asInstanceOf[SerializedLambda]
val bytes = new java.io.ByteArrayOutputStream
val os = new java.io.ObjectOutputStream(bytes)
@jodersky
jodersky / ANSI.md
Created January 15, 2023 12:23 — forked from fnky/ANSI.md
ANSI Escape Codes

ANSI Escape Sequences

Standard escape codes are prefixed with Escape:

  • Ctrl-Key: ^[
  • Octal: \033
  • Unicode: \u001b
  • Hexadecimal: \x1B
  • Decimal: 27
@jodersky
jodersky / git-wip
Last active March 29, 2023 15:32
A custom git script which is helpful if you work on many branches concurrently and forget their names
#!/bin/bash
USAGE="<pattern>"
LONG_USAGE="list most recently used branches that start with <pattern>"
# shellcheck source=/dev/null
. "$(git --exec-path)/git-sh-setup"
branches=$(git branch --sort=committerdate --list "$1*" --no-merged master --format='%(refname:short)'| tail -n 5)
for branch in $branches; do