Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

# -*- coding: utf-8 -*- 

""" 

    pygments.lexers.nix 

    ~~~~~~~~~~~~~~~~~~~ 

 

    Lexers for the NixOS Nix language. 

 

    :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS. 

    :license: BSD, see LICENSE for details. 

""" 

 

import re 

 

from pygments.lexer import RegexLexer, include 

from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ 

    Number, Punctuation, Literal 

 

__all__ = ['NixLexer'] 

 

 

class NixLexer(RegexLexer): 

    """ 

    For the `Nix language <http://nixos.org/nix/>`_. 

 

    .. versionadded:: 2.0 

    """ 

 

    name = 'Nix' 

    aliases = ['nixos', 'nix'] 

    filenames = ['*.nix'] 

    mimetypes = ['text/x-nix'] 

 

    flags = re.MULTILINE | re.UNICODE 

 

    keywords = ['rec', 'with', 'let', 'in', 'inherit', 'assert', 'if', 

                'else', 'then', '...'] 

    builtins = ['import', 'abort', 'baseNameOf', 'dirOf', 'isNull', 'builtins', 

                'map', 'removeAttrs', 'throw', 'toString', 'derivation'] 

    operators = ['++', '+', '?', '.', '!', '//', '==', 

                 '!=', '&&', '||', '->', '='] 

 

    punctuations = ["(", ")", "[", "]", ";", "{", "}", ":", ",", "@"] 

 

    tokens = { 

        'root': [ 

            # comments starting with # 

            (r'#.*$', Comment.Single), 

 

            # multiline comments 

            (r'/\*', Comment.Multiline, 'comment'), 

 

            # whitespace 

            (r'\s+', Text), 

 

            # keywords 

            ('(%s)' % '|'.join(re.escape(entry) + '\\b' for entry in keywords), Keyword), 

 

            # highlight the builtins 

            ('(%s)' % '|'.join(re.escape(entry) + '\\b' for entry in builtins), 

             Name.Builtin), 

 

            (r'\b(true|false|null)\b', Name.Constant), 

 

            # operators 

            ('(%s)' % '|'.join(re.escape(entry) for entry in operators), 

             Operator), 

 

            # word operators 

            (r'\b(or|and)\b', Operator.Word), 

 

            # punctuations 

            ('(%s)' % '|'.join(re.escape(entry) for entry in punctuations), Punctuation), 

 

            # integers 

            (r'[0-9]+', Number.Integer), 

 

            # strings 

            (r'"', String.Double, 'doublequote'), 

            (r"''", String.Single, 'singlequote'), 

 

            # paths 

            (r'[\w.+-]*(\/[\w.+-]+)+', Literal), 

            (r'\<[\w.+-]+(\/[\w.+-]+)*\>', Literal), 

 

            # urls 

            (r'[a-zA-Z][a-zA-Z0-9\+\-\.]*\:[\w%/?:@&=+$,\\.!~*\'-]+', Literal), 

 

            # names of variables 

            (r'[\w-]+\s*=', String.Symbol), 

            (r'[a-zA-Z_][\w\'-]*', Text), 

 

        ], 

        'comment': [ 

            (r'[^/*]+', Comment.Multiline), 

            (r'/\*', Comment.Multiline, '#push'), 

            (r'\*/', Comment.Multiline, '#pop'), 

            (r'[*/]', Comment.Multiline), 

        ], 

        'singlequote': [ 

            (r"'''", String.Escape), 

            (r"''\$\{", String.Escape), 

            (r"''\n", String.Escape), 

            (r"''\r", String.Escape), 

            (r"''\t", String.Escape), 

            (r"''", String.Single, '#pop'), 

            (r'\$\{', String.Interpol, 'antiquote'), 

            (r"[^']", String.Single), 

        ], 

        'doublequote': [ 

            (r'\\', String.Escape), 

            (r'\\"', String.Escape), 

            (r'\\$\{', String.Escape), 

            (r'"', String.Double, '#pop'), 

            (r'\$\{', String.Interpol, 'antiquote'), 

            (r'[^"]', String.Double), 

        ], 

        'antiquote': [ 

            (r"\}", String.Interpol, '#pop'), 

            # TODO: we should probably escape also here ''${ \${ 

            (r"\$\{", String.Interpol, '#push'), 

            include('root'), 

        ], 

    } 

 

    def analyse_text(text): 

        rv = 0.0 

        # TODO: let/in 

        if re.search(r'import.+?<[^>]+>', text): 

            rv += 0.4 

        if re.search(r'mkDerivation\s+(\(|\{|rec)', text): 

            rv += 0.4 

        if re.search(r'=\s+mkIf\s+', text): 

            rv += 0.4 

        if re.search(r'\{[a-zA-Z,\s]+\}:', text): 

            rv += 0.1 

        return rv