diff --git a/lib/rouge/lexers/cpp.rb b/lib/rouge/lexers/cpp.rb index 3fd9d1b29a..9a74e19299 100644 --- a/lib/rouge/lexers/cpp.rb +++ b/lib/rouge/lexers/cpp.rb @@ -22,10 +22,10 @@ class Cpp < C def self.keywords @keywords ||= super + Set.new(%w( - asm auto catch const_cast delete dynamic_cast explicit export - friend mutable namespace new operator private protected public - reinterpret_cast restrict size_of static_cast template this throw - throws typeid typename using virtual final override + asm auto catch const_cast delete dynamic_cast explicit export friend + mutable namespace new operator private protected public + reinterpret_cast restrict size_of static_cast this throw throws + typeid typename using virtual final override alignas alignof constexpr decltype noexcept static_assert thread_local try @@ -57,7 +57,8 @@ def self.reserved dq = /\d('?\d)*/ prepend :statements do - rule %r/class\b/, Keyword, :classname + rule %r/(class|struct)\b/, Keyword, :classname + rule %r/template\b/, Keyword, :template rule %r/\d+(\.\d+)?(?:h|(?:min)|s|(?:ms)|(?:us)|(?:ns))/, Num::Other rule %r((#{dq}[.]#{dq}?|[.]#{dq})(e[+-]?#{dq}[lu]*)?)i, Num::Float rule %r(#{dq}e[+-]?#{dq}[lu]*)i, Num::Float @@ -77,6 +78,12 @@ def self.reserved rule %r/[.]{3}/, Operator mixin :whitespace end + + state :template do + rule %r/>/, Punctuation, :pop! + rule %r/typename\b/, Keyword, :classname + mixin :root + end end end end diff --git a/spec/visual/samples/cpp b/spec/visual/samples/cpp index abd7f6e5be..d09a703fd9 100644 --- a/spec/visual/samples/cpp +++ b/spec/visual/samples/cpp @@ -78,6 +78,22 @@ double distance = [](double x, double y, double xx, double yy) -> double { return abs(x-xx) + abs(y-yy); }; +// templates +namespace N +{ + template + class Y // template definition + { + void mf() { } + }; +} +template class N::Y; +template void N::Y::mf(); +template struct Z; +template concept C1 = sizeof(T) != sizeof(int); +template struct S1 { }; +template using Ptr = T*; + // variadic template template void forward_args(F f, Args... args) {