A start at *.raku filetype highlighters. Chipping away locally and not all setup yet. So, I’m able to share through this platform rather than a repo at the moment. Anyone looking to or wanting a bit of colour for their Raku files just drop it in/as autoload/raku.kak and hackity hack hack.
raku.kak
# https://www.raku.org/
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
# Adapted from source:
# <https://github.com/hankache/raku.nanorc>
#
# Detection
# ‾‾‾‾‾‾‾‾‾
hook global BufCreate .*\.raku(mod|doc|test)?$ %{
set-option buffer filetype raku
}
# Initialization
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾
hook global WinSetOption filetype=raku %{
require-module raku
set-option window static_words %opt{raku_static_words}
# cleanup trailing whitespaces when exiting insert mode
hook window ModeChange pop:insert:.* -group raku-trim-indent %{ try %{ execute-keys -draft xs^\h+$<ret>d } }
hook window InsertChar \n -group raku-insert raku-insert-on-new-line
hook window InsertChar \n -group raku-indent raku-indent-on-new-line
hook window InsertChar \{ -group raku-indent raku-indent-on-opening-curly-brace
hook window InsertChar \} -group raku-indent raku-indent-on-closing-curly-brace
hook -once -always window WinSetOption filetype=.* %{ remove-hooks window raku-.+ }
}
hook -group raku-highlight global WinSetOption filetype=raku %{
add-highlighter window/raku ref raku
hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/raku }
}
provide-module raku %§
# Highlighters
# ‾‾‾‾‾‾‾‾‾‾‾‾
add-highlighter shared/raku regions
add-highlighter shared/raku/code default-region group
add-highlighter shared/raku/dquote region %{(?<!')"} %{(?<!\\)(\\\\)*"} group
add-highlighter shared/raku/squote region %{'} %{(?<!\\)'} group
# Comments - single line
add-highlighter shared/raku/comment_line region %{#(?![|=])} %{$} fill comment
# Pod Declarator block/single line
add-highlighter shared/raku/pod_block region %{^=begin [A-Za-z0-9]*?} %{^=end [A-Za-z0-9]*?} fill documentation
add-highlighter shared/raku/pod_line region %{#(?=[|=])} %{$} fill documentation
# Heredocs
add-highlighter shared/raku/heredocs region -match-capture %{qq?:to/END/;} %{^END} fill string
# Double quoted strings
add-highlighter shared/raku/dquote/ fill string
add-highlighter shared/raku/dquote/ regex \{.*?\} 0:function
# Single quoted strings
add-highlighter shared/raku/squote/ fill string
# Discolour loading a modules FQN
add-highlighter shared/raku/code/ regex %{^(use|need|import)(?S)(.+);$} 2:default+fa
# Variables
add-highlighter shared/raku/code/ regex %{[$@%&](\.|!|\^)?([A-Za-z]|_)} 0:variable
add-highlighter shared/raku/code/ regex %{[$@%&](\.|!|\^)?([A-Za-z]|_)([A-Za-z0-9]|-|_)*([A-Za-z0-9]|_)} 0:variable
add-highlighter shared/raku/code/ regex %{[$@%&](\?|\*)([A-Z])([A-Z]|-)*([A-Z])} 0:variable
# Angle brackets
add-highlighter shared/raku/code/ regex %{<([A-Za-z0-9]|-| |\.|_|/)*>} 0:default
add-highlighter shared/raku/code/ regex %{\$<([A-Za-z0-9]|-|_)*>} 0:default
add-highlighter shared/raku/code/ regex %{(<|>)} 0:default
# Versions
add-highlighter shared/raku/code/ regex %{\b(v([0-9]|\*)(\.([A-Za-z0-9]|\*))*)\b} 0:default
# Sym
add-highlighter shared/raku/code/ regex %{:sym} 0:attribute
#Regex
add-highlighter shared/raku/code/ regex %{(?S)(m|rx|tr|TR|s|S)?/.*/} 0:attribute
#Regex Match
add-highlighter shared/raku/code/ regex %{\$/} 0:builtin
# Numbers
add-highlighter shared/raku/code/ regex %{\b([0-9]+)\b} 0:value
add-highlighter shared/raku/code/ regex %{\b([0-9]*(\.|_)[0-9]+)\b} 0:value
add-highlighter shared/raku/code/ regex %{\b([0-9]+(e)[0-9]+)\b} 0:value
add-highlighter shared/raku/code/ regex %{\b([0-9]*(\+)*([0-9]|NaN\\|Inf\\)+i)\b} 0:value
#Nativecall types
add-highlighter shared/raku/code/ regex %{\b(int8|int16|int32|int64|uint8|uint16|uint32|uint64|long|longlong|num32|num64|size_t|bool|CArray|Pointer)\b} 0:type
# Traits
add-highlighter shared/raku/code/ regex %{\b(rw|required|native|repr|export|symbol)\b} 0:keyword
# Booleans
add-highlighter shared/raku/code/ regex %{\b(True|False)\b} 0:builtin
# Ops
add-highlighter shared/raku/code/ regex %{\b(eq|ne|gt|lt|le|ge|div|gcd|lcm|leg|cmp|ff)\b} 0:operator
add-highlighter shared/raku/code/ regex %{\b(=|=>|==|!=|<|>|<=|>=|\+|\*|-|/|~|\*\*|%|%%|<=>|~~|\+\+|--|\?|!|\.\.|\.\.\^|\^\.\.|\^\.\.\^|\^|\.\.\.|\||\.)\b} 0:operator
add-highlighter shared/raku/code/ regex %{\b(infix:<[+-]>)\b} 0:function
# Grammar
evaluate-commands %sh{
# Exceptions
exceptions="X::AdHoc X::Anon::Augment X::Anon::Multi X::Assignment::RO X::Attribute::NoPackage
X::Attribute::Package X::Attribute::Undeclared X::Augment::NoSuchType X::Bind
X::Bind::NativeType X::Bind::Slice X::Caller::NotDynamic X::Channel::ReceiveOnClosed
X::Channel::SendOnClosed X::Comp X::Composition::NotComposable X::Constructor::Positional
X::ControlFlow X::ControlFlow::Return X::DateTime::TimezoneClash X::Declaration::Scope
X::Declaration::Scope::Multi X::Does::TypeObject X::Eval::NoSuchLang X::Export::NameClash
X::Inheritance::NotComposed X::Inheritance::Unsupported X::IO X::IO::Chdir X::IO::Chmod
X::IO::Copy X::IO::Cwd X::IO::Dir X::IO::DoesNotExist X::IO::Link X::IO::Mkdir X::IO::Move
X::IO::Rename X::IO::Rmdir X::IO::Symlink X::IO::Unlink X::Method::InvalidQualifier
X::Method::NotFound X::Method::Private::Permission X::Method::Private::Unqualified
X::Mixin::NotComposable X::NoDispatcher X::Numeric::Real X::NYI X::Obsolete X::OS
X::OutOfRange X::Package::Stubbed X::Parameter::Default X::Parameter::MultipleTypeConstraints
X::Parameter::Placeholder X::Parameter::Twigil X::Parameter::WrongOrder X::Phaser::Multiple
X::Phaser::PrePost X::Placeholder::Block X::Placeholder::Mainline X::Pod X::Proc::Async
X::Proc::Async::AlreadyStarted X::Proc::Async::CharsOrBytes X::Proc::Async::MustBeStarted
X::Proc::Async::OpenForWriting X::Proc::Async::TapBeforeSpawn X::Proc::Unsuccessful
X::Promise::CauseOnlyValidOnBroken X::Promise::Vowed X::Redeclaration X::Role::Initialization
X::Seq::Consumed X::Sequence::Deduction X::Signature::NameClash X::Signature::Placeholder
X::Str::Numeric X::StubCode X::Syntax X::Syntax::Augment::WithoutMonkeyTyping
X::Syntax::Comment::Embedded X::Syntax::Confused X::Syntax::InfixInTermPosition
X::Syntax::Malformed X::Syntax::Missing X::Syntax::NegatedPair X::Syntax::NoSelf
X::Syntax::Number::RadixOutOfRange X::Syntax::P5 X::Syntax::Regex::Adverb
X::Syntax::Regex::SolitaryQuantifier X::Syntax::Reserved X::Syntax::Self::WithoutObject
X::Syntax::Signature::InvocantMarker X::Syntax::Term::MissingInitializer X::Syntax::UnlessElse
X::Syntax::Variable::Match X::Syntax::Variable::Numeric X::Syntax::Variable::Twigil
X::Temporal X::Temporal::InvalidFormat X::TypeCheck X::TypeCheck::Assignment X::TypeCheck::Binding
X::TypeCheck::Return X::TypeCheck::Splice X::Undeclared"
# Keywords
keywords="my our class role grammar is does sub method submethod try CATCH default when if
elsif else unless with orwith without for given proceed succeed loop while until
repeat module use need import require unit constant enum multi return has token
rule make made proto state augment but anon supersede let subset gather returns
return-rw"
# Methods
methods="ACCEPTS ASSIGN-KEY ASSIGN-POS AT-KEY AT-POS Array BIND-KEY BIND-POS Bag BagHash Bool
Bridge CALL-ME CREATE Capture Channel Complex DELETE-KEY DELETE-POS DESTROY DISTROnames
Date DateTime EVAL EXISTS-KEY EXISTS-POS Hash IO IO::Notification.watch-path Instant
Int KERNELnames List Map Mix MixHash NFC NFD NFKC NFKD Num Numeric Promise Rat Real
SPEC Set SetHash Slip Str Supply VMnames WHERE WHEREFORE WHICH WHY abs abs2rel absolute
accept accessed acquire act action actions add add_attribute add_enum_value add_fallback
add_method add_parent add_private_method add_role add_trustee adverb after all allocate
allof allowed alternative-names annotations antipair antipairs any anyof app_lifetime
append arch archname args arity assuming ast at attributes auth backtrace base base-repeating
basename batch bind-stderr bind-stdin bind-stdout bind-udp bits bless block bool-only
bounds break broken build-date bytes cache calling-package can cancel candidates cando
canonpath caps caption capture catdir categorize categorize-list catfile catpath cause
ceiling changed channel chdir child child-name child-typename chmod chomp chunks classify
classify-list cleanup clone close close-stdin closed code codes collate column comb
combinations command comment compiler compose compose_type composer condition config
configure_destroy configure_type_checking conj connect constraints construct contains
contents copy count count-only cpu-cores cpu-usage create_type cue curdir curupdir d
day day-of-month day-of-week day-of-year daycount days-in-month declaration decode
decoder deepmap default defined delayed denominator desc destroyers devnull did-you-mean
dir-sep dirname do does done duckmap dynamic e eager earlier elems emit enclosing encode
encoder encoding end ends-with enum_from_value enum_value_list enum_values enums eof
exception excludes-max excludes-min exitcode exp expected extension f fail feature file
filename find_method find_method_qualified finish first flat flatmap floor flush fmt
format formatter freeze from from-list from-loop from-posix full get get_value getc
gist got grab grabpairs grep handle handled handles hardware has_accessor hash head
headers hh-mm-ss hidden hides hour how hyper id illegal im in in-timezone indent indices
infinite infix install_method_cache instead int-bounds interval invalid-str invert
invocant is-absolute is-hidden is-initial-thread is-int is-lazy is-leap-year is-relative
is-routine is-setting is-win isNaN is_trusted is_type isa item iterator join keep kept
key keyof keys kill kv kxxv l lang last later lazy leading level line lines link list
listen live local lock lookup lsb made make map match max maxpairs merge message method
method_table methods migrate min minmax minpairs minute misplaced mode modified month
move msb multi multiness my name named named_names narrow native-descriptor new
new-from-daycount new-from-pairs new_type next next-handle nl-in nl-out nodemap none
norm not note now nude numerator of offset offset-in-hours offset-in-minutes old
on-close on-switch one open opened operation optional ords orig os-error osname
out-buffer package package-kind package-name packages pair pairs pairup parameter params
parent parent-name parents parse parsefile parts path path-sep payload peer-host peer-port
perl permutations phaser pick pickpairs pid placeholder plus polar poll polymod pop pos
positional posix postfix postmatch precomp-ext precomp-target pred prefix prematch prepend
print print-nl print-to printf private private_method_table proc produce promise protect
pull-one push push-all push-at-least push-exactly push-until-lazy put qualifier-type
quit r race radix rand range raw re read readchars readonly ready reallocate reals reason
rebless receive recv redispatcher redo reduce rel2abs relative release rename repeated
replacement reserved resolve restore result resume rethrow reverse right role roles_to_compose
rolish roll rootdir roots rotor round routine-type run rwx s say schedule-on scheduler
scope sec second seek self send set-instruments set_hidden set_name set_package set_rw
set_value setup_finalization shape share shell shift sibling sigil sign signal signals
signature sink sink-all skip skip-at-least skip-at-least-pull-one skip-one slurp slurp-rest
slurpy so socket-host socket-port sort source source-package spawn splice split splitdir
splitpath spurt sqrt squish stable start started starts-with status stderr stdout sub_signature
subbuf subbuf-rw subname subparse subst subst-mutate substr-eq substr-rw succ sum symlink
t tail take tap target target-name tell then throttle throw timezone tmpdir to to-posix
today toggle total trailing trans tree trim trim-leading trim-trailing truncate truncated-to
trusts try_acquire trying twigil type type_captures typename udp uncaught_handler unimatch
uniname uninames uniprop uniprops unique unival univals unlink unlock unpack unpolar unshift
unwrap updir utc value values variable verbose-config version volume vow w wait watch watch-path
week week-number week-year weekday-of-month what when whole-second words workaround wrap write
write-to x yada year yield yyyy-mm-dd z zip zip-latest WHAT WHO HOW DEFINITE VAR mro BUILD"
# Phasers
phasers="BEGIN CHECK INIT END CLOSE ENTER LEAVE KEEP UNDO PRE POST FIRST NEXT LAST CATCH CONTROL QUIT DOC"
# Pragmas
pragmas="MONKEY-SEE-NO-EVAL MONKEY-TYPING MONKEY-GUTS MONKEY experimental fatal lib newline nqp"
# Subs
subroutines="Bool EVALFILE MAIN T USAGE abs acos acosec acosech acosh acotan acotanh asec asech asin
asinh atan atan2 atanh atomic-assign atomic-dec-fetch atomic-fetch atomic-fetch-add
atomic-fetch-dec atomic-fetch-inc atomic-fetch-sub atomic-inc-fetch await bag callframe
callsame callwith cas categorize ceiling cglobal chars chdir chmod chomp chop chr chrs
cis classify codes comb combinations cos cosec cosech cosh cotan cotanh cross defined
die dir elems end exit exp explicitly-manage expmod fc first flat flip floor full-barrier
gist grep index indir is-prime item join keys kv lastcall lc lines
log log10 map mix mkdir nativecast nativesizeof nextcallee nextsame nextwith open ord
ords pack pairs parse-base parse-names periods permutations pick pop print produce prompt
push put rand reduce repeated report reverse rindex rmdir roll roots rotate round roundrobin
run samecase samemark samewith say sech set shell shift signal sin sinh sleep sleep-timer
sleep-until slip slurp snap snapper sort splice split sprintf spurt sqrt squish srand
subbuf-rw substr sum take take-rw tan tanh tc tclc trim trim-leading trim-trailing truncate
uc uniparse unique unival unshift val values warn wordcase words zip"
# Test Module
tests="plan done-testing bail-out todo skip skip-rest diag subtest pass flunk ok nok cmp-ok
is-deeply isnt is-approx like unlike use-ok isa-ok does-ok can-ok dies-ok lives-ok
eval-dies-ok eval-lives-ok throws-like fails-like"
# Types
types="Any Array Associative AST atomicint Attribute Backtrace Backtrace::Frame Bag Baggy BagHash
Blob Block Bool Buf Callable CallFrame Cancellation Capture Channel Code compiler Complex
ComplexStr Cool CurrentThreadScheduler Cursor Date Dateish DateTime Distro Duration Encoding
Exception Failure FatRat Grammar Hash HyperWhatever Instant Int IntStr IO IO::ArgFiles
IO::CatHandle IO::Handle IO::Notification IO::Path IO::Path::Cygwin IO::Path::QNX IO::Path::Unix
IO::Path::Win32 IO::Pipe IO::Socket IO::Socket::Async IO::Socket::INET IO::Spec IO::Spec::Cygwin
IO::Spec::QNX IO::Spec::Unix IO::Spec::Win32 IO::Special Iterable Iterator Junction Kernel
Label List Lock Lock::Async Macro Map Match Metamodel::AttributeContainer Metamodel::C3MRO
Metamodel::ClassHOW Metamodel::EnumHOW Metamodel::Finalization Metamodel::MethodContainer
Metamodel::MROBasedMethodDispatch Metamodel::MultipleInheritance Metamodel::Naming
Metamodel::Primitives Metamodel::PrivateMethodContainer Metamodel::RoleContainer
Metamodel::Trusting Method Mix MixHash Mixy Mu NFC NFD NFKC NFKD Nil Num Numeric NumStr
ObjAt Order Pair Parameter Perl Pod::Block Pod::Block::Code Pod::Block::Comment
Pod::Block::Declarator Pod::Block::Named Pod::Block::Para Pod::Block::Table Pod::Heading
Pod::Item Positional PositionalBindFailover Proc Proc::Async Promise Proxy PseudoStash
QuantHash Range Rat Rational RatStr Real Regex Routine Scalar Scheduler Semaphore Seq Set
SetHash Setty Signature Slip Stash Str StrDistance Stringy Sub Submethod Supplier
Supplier::Preserving Supply Systemic Tap Telemetry Telemetry::Instrument::Thread
Telemetry::Instrument::Usage Telemetry::Period Telemetry::Sampler Thread ThreadPoolScheduler
UInt Uni utf8 Variable Version VM Whatever WhateverCode WrapHandle int uint num str"
join() { sep=$2; eval set -- $1; IFS="$sep"; echo "$*"; }
# Add the language's grammar to the static completion list
printf %s\\n "declare-option str-list raku_static_words $(join "${exceptions} ${keywords} ${methods} ${phasers} ${pragmas} ${subroutines} ${tests} ${types}" ' ')"
# Highlight keywords
printf %s "
add-highlighter shared/raku/code/ regex \b($(join "${exceptions}" '|'))\b 0:default
add-highlighter shared/raku/code/ regex \b($(join "${keywords}" '|'))\b 0:keyword
add-highlighter shared/raku/code/ regex \b($(join "${methods}" '|'))\b 0:function
add-highlighter shared/raku/code/ regex \b($(join "${phasers}" '|'))\b 0:function
add-highlighter shared/raku/code/ regex \b($(join "${pragmas}" '|'))\b 0:function
add-highlighter shared/raku/code/ regex \b($(join "${subroutines}" '|'))\b 0:function
add-highlighter shared/raku/code/ regex \b($(join "${tests}" '|'))\b 0:default+u
add-highlighter shared/raku/code/ regex \b($(join "${types}" '|'))\b 0:type
"
}
# Commands
# ‾‾‾‾‾‾‾‾
define-command -hidden raku-insert-on-new-line %~
evaluate-commands -draft -itersel %=
# copy # comments prefix and following white spaces
try %{ execute-keys -draft <semicolon><c-s>kx s ^\h*\K#\h* <ret> y<c-o>P<esc> }
=
~
define-command -hidden raku-indent-on-new-line %~
evaluate-commands -draft -itersel %=
# preserve previous line indent
try %{ execute-keys -draft <semicolon>K<a-&> }
# indent after lines ending with { or (
try %[ execute-keys -draft kx <a-k> [{(]\h*$ <ret> j<a-gt> ]
# cleanup trailing white spaces on the previous line
try %{ execute-keys -draft kx s \h+$ <ret>d }
# align to opening paren of previous line
try %{ execute-keys -draft [( <a-k> \A\([^\n]+\n[^\n]*\n?\z <ret> s \A\(\h*.|.\z <ret> '<a-;>' & }
# indent after a switch's case/default statements
try %[ execute-keys -draft kx <a-k> ^\h*(case|default).*:$ <ret> j<a-gt> ]
# indent after if|else|while|for
try %[ execute-keys -draft <semicolon><a-F>)MB <a-k> \A(if|else|while|for)\h*\(.*\)\h*\n\h*\n?\z <ret> s \A|.\z <ret> 1<a-&>1<a-,><a-gt> ]
# deindent closing brace(s) when after cursor
try %[ execute-keys -draft x <a-k> ^\h*[})] <ret> gh / [})] <ret> m <a-S> 1<a-&> ]
=
~
define-command -hidden raku-indent-on-opening-curly-brace %[
# align indent with opening paren when { is entered on a new line after the closing paren
try %[ execute-keys -draft -itersel h<a-F>)M <a-k> \A\(.*\)\h*\n\h*\{) <ret> s \A|.\z <ret> 1<a-&> ]
]
define-command -hidden raku-indent-on-closing-curly-brace %[
# align to opening curly brace when alone on a line
try %[ execute-keys -itersel -draft <a-h><a-k>^\h+\}$<ret>hms\A|.\z<ret>1<a-&> ]
]
§
Raku highlighter screenshot with a solarized-dark editor colour scheme:
