# Raku filetype highlighter (know previously as Perl6)

**URL:** <https://discuss.kakoune.com/t/raku-filetype-highlighter-know-previously-as-perl6/2810>\
**Category:** Plugins\
**Tags:** highlighter, plugins, language\
**Created:** [January 10, 2026, 8:03am UTC](https://discuss.kakoune.com/t/raku-filetype-highlighter-know-previously-as-perl6/2810 "2026-01-10T08:03:11Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![duncode](https://discuss.kakoune.com/letter_avatar_proxy/v4/letter/d/977dab/32.png) [@duncode](https://discuss.kakoune.com/u/duncode)\
**Post date:** [January 10, 2026, 8:03am UTC](https://discuss.kakoune.com/t/raku-filetype-highlighter-know-previously-as-perl6/2810/1 "2026-01-10T08:03:12Z")

</div>

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**
>
> ```auto
> # 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:

 ![Screenshot_From_2026_01_10_17_13_42](https://discuss.kakoune.com/uploads/default/original/2X/7/703f7a4b8482e5ebb3dd77c4e4a7c5734de055ee.png)
