-module(string_width_ffi). -export([ansi_re/0, scan_poslen/2, fold_codepoints/3, utf_codepoint_to_string/1]). -on_load(load/0). load() -> {ok, AnsiRe} = re:compile("[\x1B\x9B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\x07|\x1B\x5C|\x9C))|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))", [multiline]), ok = persistent_term:put({?MODULE, ansi_re}, AnsiRe), ok. ansi_re() -> persistent_term:get({?MODULE, ansi_re}). scan_poslen(Re, Str) -> case re:run(Str, Re, [global]) of nomatch -> []; {match, Matches} -> [Match || [Match] <- Matches] end. fold_codepoints(Binary, State, Fun) -> case Binary of <> -> fold_codepoints(Rest, Fun(State, Cp), Fun); _ -> State end. utf_codepoint_to_string(Cp) -> <>.