212 lines
4.8 KiB
Ruby
212 lines
4.8 KiB
Ruby
# -*- coding: utf-8 -*- #
|
|
# frozen_string_literal: true
|
|
|
|
module Rouge
|
|
module Lexers
|
|
class Nix < RegexLexer
|
|
title 'Nix'
|
|
desc 'The Nix expression language (https://nixos.org/nix/manual/#ch-expression-language)'
|
|
tag 'nix'
|
|
aliases 'nixos'
|
|
filenames '*.nix'
|
|
|
|
state :whitespaces do
|
|
rule %r/^\s*\n\s*$/m, Text
|
|
rule %r/\s+/, Text
|
|
end
|
|
|
|
state :comment do
|
|
rule %r/#.*$/, Comment
|
|
rule %r(/\*), Comment, :multiline_comment
|
|
end
|
|
|
|
state :multiline_comment do
|
|
rule %r(\*/), Comment, :pop!
|
|
rule %r/./, Comment
|
|
end
|
|
|
|
state :number do
|
|
rule %r/[0-9]/, Num::Integer
|
|
end
|
|
|
|
state :null do
|
|
rule %r/(null)/, Keyword::Constant
|
|
end
|
|
|
|
state :boolean do
|
|
rule %r/(true|false)/, Keyword::Constant
|
|
end
|
|
|
|
state :binding do
|
|
rule %r/[a-zA-Z_][a-zA-Z0-9-]*/, Name::Variable
|
|
end
|
|
|
|
state :path do
|
|
word = "[a-zA-Z0-9\._-]+"
|
|
section = "(\/#{word})"
|
|
prefix = "[a-z\+]+:\/\/"
|
|
root = /#{section}+/.source
|
|
tilde = /~#{section}+/.source
|
|
basic = /#{word}(\/#{word})+/.source
|
|
url = /#{prefix}(\/?#{basic})/.source
|
|
rule %r/(#{root}|#{tilde}|#{basic}|#{url})/, Str::Other
|
|
end
|
|
|
|
state :string do
|
|
rule %r/"/, Str::Double, :double_quoted_string
|
|
rule %r/''/, Str::Double, :indented_string
|
|
end
|
|
|
|
state :string_content do
|
|
rule %r/\\./, Str::Escape
|
|
rule %r/\$\$/, Str::Escape
|
|
rule %r/\${/, Str::Interpol, :string_interpolated_arg
|
|
end
|
|
|
|
state :indented_string_content do
|
|
rule %r/'''/, Str::Escape
|
|
rule %r/''\$/, Str::Escape
|
|
rule %r/\$\$/, Str::Escape
|
|
rule %r/''\\./, Str::Escape
|
|
rule %r/\${/, Str::Interpol, :string_interpolated_arg
|
|
end
|
|
|
|
state :string_interpolated_arg do
|
|
mixin :expression
|
|
rule %r/}/, Str::Interpol, :pop!
|
|
end
|
|
|
|
state :indented_string do
|
|
mixin :indented_string_content
|
|
rule %r/''/, Str::Double, :pop!
|
|
rule %r/./, Str::Double
|
|
end
|
|
|
|
state :double_quoted_string do
|
|
mixin :string_content
|
|
rule %r/"/, Str::Double, :pop!
|
|
rule %r/./, Str::Double
|
|
end
|
|
|
|
state :operator do
|
|
rule %r/(\.|\?|\+\+|\+|!=|!|\/\/|\=\=|&&|\|\||->|\/|\*|-|<|>|<=|=>)/, Operator
|
|
end
|
|
|
|
state :assignment do
|
|
rule %r/(=)/, Operator
|
|
rule %r/(@)/, Operator
|
|
end
|
|
|
|
state :accessor do
|
|
rule %r/(\$)/, Punctuation
|
|
end
|
|
|
|
state :delimiter do
|
|
rule %r/(;|,|:)/, Punctuation
|
|
end
|
|
|
|
state :atom_content do
|
|
mixin :expression
|
|
rule %r/\)/, Punctuation, :pop!
|
|
end
|
|
|
|
state :atom do
|
|
rule %r/\(/, Punctuation, :atom_content
|
|
end
|
|
|
|
state :list do
|
|
rule %r/\[/, Punctuation, :list_content
|
|
end
|
|
|
|
state :list_content do
|
|
rule %r/\]/, Punctuation, :pop!
|
|
mixin :expression
|
|
end
|
|
|
|
state :set do
|
|
rule %r/{/, Punctuation, :set_content
|
|
end
|
|
|
|
state :set_content do
|
|
rule %r/}/, Punctuation, :pop!
|
|
mixin :expression
|
|
end
|
|
|
|
state :expression do
|
|
mixin :ignore
|
|
mixin :comment
|
|
mixin :boolean
|
|
mixin :null
|
|
mixin :number
|
|
mixin :path
|
|
mixin :string
|
|
mixin :keywords
|
|
mixin :operator
|
|
mixin :accessor
|
|
mixin :assignment
|
|
mixin :delimiter
|
|
mixin :binding
|
|
mixin :atom
|
|
mixin :set
|
|
mixin :list
|
|
end
|
|
|
|
state :keywords do
|
|
mixin :keywords_namespace
|
|
mixin :keywords_declaration
|
|
mixin :keywords_conditional
|
|
mixin :keywords_reserved
|
|
mixin :keywords_builtin
|
|
end
|
|
|
|
state :keywords_namespace do
|
|
keywords = %w(with in inherit)
|
|
rule %r/(?:#{keywords.join('|')})\b/, Keyword::Namespace
|
|
end
|
|
|
|
state :keywords_declaration do
|
|
keywords = %w(let)
|
|
rule %r/(?:#{keywords.join('|')})\b/, Keyword::Declaration
|
|
end
|
|
|
|
state :keywords_conditional do
|
|
keywords = %w(if then else)
|
|
rule %r/(?:#{keywords.join('|')})\b/, Keyword
|
|
end
|
|
|
|
state :keywords_reserved do
|
|
keywords = %w(rec assert map)
|
|
rule %r/(?:#{keywords.join('|')})\b/, Keyword::Reserved
|
|
end
|
|
|
|
state :keywords_builtin do
|
|
keywords = %w(
|
|
abort
|
|
baseNameOf
|
|
builtins
|
|
derivation
|
|
fetchTarball
|
|
import
|
|
isNull
|
|
removeAttrs
|
|
throw
|
|
toString
|
|
)
|
|
rule %r/(?:#{keywords.join('|')})\b/, Keyword::Reserved
|
|
end
|
|
|
|
state :ignore do
|
|
mixin :whitespaces
|
|
end
|
|
|
|
state :root do
|
|
mixin :ignore
|
|
mixin :expression
|
|
end
|
|
|
|
start do
|
|
end
|
|
end
|
|
end
|
|
end
|