Open Source Consultant, Software Developer and System Administrator

If you are interrested in hiring a consultant for the effective use of open source software on an enterprise grade, take a look around in the About section to see, what I have to offer.

Blog and snippets

Various snippets or code parts I found useful, so I keep them here for reference.

Using gocr and flameshot to get text from screenshots

From time to time I have the need to get text from an image, when someone shares a screen-shot, but not the URL in it or when I want to copy code from a stopped youtube video. So ideally I want to select a region of my screen and turn that into text.

First install gocr and flameshot. Then create a script, that runs gocr and opens the resulting text (in my case I want to open a terminal with vim). E.g. ~/bin/ocr:

#!/bin/sh
rxvt -e sh -c "gocr -i \"$1\" | vim -"

Then create a "desktop" entry for flameshot to pick up. ~/.local/share/applications/ocr.desktop:

[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Exec=.../bin/ocr %f
Name=OCR
Categories=Graphics;

(Note, that the path there is absolute, or you have to figure out, what works for you... I couldn't be bothered to look into this)

Then start flameshot gui (I have that on my Print Screen-key), select the region to OCR, press CTRL-o (or click the button to open the screenshot with an application), then pick the OCR-Application from the desktop entry, which then opens the text.

ES6 object property shorthand with Groovy

Recently someone asked on StackOverflow whether there is an equivalent in Groovy for the JavaScript shorthand for properties of the object literal. It basically looks like this:

const a = 'foo';
const b = 42;
const c = {};
const obj = { a, b, c };
// the same as: const obj = { a: a, b: b, c: c };

While this feature is not supported in Groovy directly, it's easy to reproduce using a very underused feature: a macro. Macros are supported in Groovy since 2.5.

Create new file to contain all macros. E.g. Macros.groovy:

import org.codehaus.groovy.ast.tools.GeneralUtils
import org.codehaus.groovy.macro.runtime.*
import org.codehaus.groovy.ast.expr.*
import org.codehaus.groovy.syntax.*

class Macros {
    @Macro
    static Expression mapOf(MacroContext ctx, final Expression... exps) {
        return new MapExpression(
            exps.collect{
                new MapEntryExpression(GeneralUtils.constX(it.getText()), it)
            }
        )
    }
}

Then compile this file (this is important to do first, or else Groovy gets confused when something references the class, but it's not there):

# groovyc Macros.groovy

Next make the macro known. There must a file META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModule in the classpath containing the following lines to make Macros from above work:

moduleName=Some name
moduleVersion=0.1-SNAPSHOT
extensionClasses=Macros

And then finally try it out:

def labels=["a", "b"]
def values=[1, 2]
println(
    [labels, values]
        .transpose()
        .collect{ label, value -> 
            mapOf(label,value) 
        }
)

And run it:

# groovy test.groovy
[[label:a, value:1], [label:b, value:2]]

Advent of code 2020

This year I am doing my first Advent of code ever using in Clojure. Advent of code gives daily code challenges, consisting of two parts building on each other.

I used this to try out vim-iced to replace vim-fireplace and tried out Kaocha.

Iced

Pros:

  • Starts its own REPL, so no need to fiddle with cider plugins etc.

  • Good integration into NeoVim.

  • Code evaluation is shown inline

  • Macro-expand into buffer

Cons:

  • The CLI tool needs a local installation of node to run shadow-cljs.

  • Code navigation only works when reloading a name-space.

  • Multiple crashes of NeoVim over the course of the month.

Kaocha

I replaced lein-test-refresh with Kaocha as my watching test runner. I really like the workflow of having my test run automatically every time I save a file.

Pros:

  • Ability to focus tests with meta annotations.

  • Colored, pretty printed output on test failure.

  • Seamless integration with clojure.test and Leiningen.

  • Many plugins and helpers (e.g. notify on test failure/success with a configured tool).

Cons:

  • Found no way to stop an long running test other than Ctrl-C.

  • The diffed output can be so overwhelming, I re-run tests sometimes with lein test just to get the plain data.

  • Output is captured and only prints once the test is finished; so "debug-println" is delayed and might never print in case of infinite loops.

Conclusion

While I am not convinced that I will stick with Iced, I really liked Kaocha.

The code is on GitHub