summaryrefslogtreecommitdiff
path: root/rc/core/python.kak
blob: f33fef2443377571f6b539e4ec10bab2e0dc1099 (plain)
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# http://python.org
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾

# Detection
# ‾‾‾‾‾‾‾‾‾

hook global BufCreate .*[.](py) %{
    set-option buffer filetype python
}

# Highlighters & Completion
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾

add-highlighter shared/ regions -default code python \
    docstring     '"""' '"""'            '' \
    docstring     "'''" "'''"            '' \
    double_string '"'   (?<!\\)(\\\\)*"  '' \
    single_string "'"   (?<!\\)(\\\\)*'  '' \
    comment       '#'   '$'              ''

# Integer formats
add-highlighter shared/python/code regex '(?i)\b0b[01]+l?\b' 0:value
add-highlighter shared/python/code regex '(?i)\b0x[\da-f]+l?\b' 0:value
add-highlighter shared/python/code regex '(?i)\b0o?[0-7]+l?\b' 0:value
add-highlighter shared/python/code regex '(?i)\b([1-9]\d*|0)l?\b' 0:value
# Float formats
add-highlighter shared/python/code regex '\b\d+[eE][+-]?\d+\b' 0:value
add-highlighter shared/python/code regex '(\b\d+)?\.\d+\b' 0:value
add-highlighter shared/python/code regex '\b\d+\.' 0:value
# Imaginary formats
add-highlighter shared/python/code regex '\b\d+\+\d+[jJ]\b' 0:value

add-highlighter shared/python/double_string fill string
add-highlighter shared/python/single_string fill string

add-highlighter shared/python/docstring/ regions -default docstring py-docstring \
    python '>>> \K'    '\z' '' \
    python '\.\.\. \K' '\z' ''
add-highlighter shared/python/docstring/py-docstring/python    ref python
add-highlighter shared/python/docstring/py-docstring/docstring fill string

add-highlighter shared/python/comment       fill comment

%sh{
    # Grammar
    values="True|False|None|self|inf"
    meta="import|from"

    # attributes and methods list based on https://docs.python.org/3/reference/datamodel.html
    attributes="__annotations__|__closure__|__code__|__defaults__|__dict__|__doc__"
    attributes="${attributes}|__globals__|__kwdefaults__|__module__|__name__|__qualname__"
    methods="__abs__|__add__|__aenter__|__aexit__|__aiter__|__and__|__anext__"
    methods="${methods}|__await__|__bool__|__bytes__|__call__|__complex__|__contains__"
    methods="${methods}|__del__|__delattr__|__delete__|__delitem__|__dir__|__divmod__"
    methods="${methods}|__enter__|__eq__|__exit__|__float__|__floordiv__|__format__"
    methods="${methods}|__ge__|__get__|__getattr__|__getattribute__|__getitem__"
    methods="${methods}|__gt__|__hash__|__iadd__|__iand__|__ifloordiv__|__ilshift__"
    methods="${methods}|__imatmul__|__imod__|__imul__|__index__|__init__"
    methods="${methods}|__init_subclass__|__int__|__invert__|__ior__|__ipow__"
    methods="${methods}|__irshift__|__isub__|__iter__|__itruediv__|__ixor__|__le__"
    methods="${methods}|__len__|__length_hint__|__lshift__|__lt__|__matmul__"
    methods="${methods}|__missing__|__mod__|__mul__|__ne__|__neg__|__new__|__or__"
    methods="${methods}|__pos__|__pow__|__radd__|__rand__|__rdivmod__|__repr__"
    methods="${methods}|__reversed__|__rfloordiv__|__rlshift__|__rmatmul__|__rmod__"
    methods="${methods}|__rmul__|__ror__|__round__|__rpow__|__rrshift__|__rshift__"
    methods="${methods}|__rsub__|__rtruediv__|__rxor__|__set__|__setattr__"
    methods="${methods}|__setitem__|__set_name__|__slots__|__str__|__sub__"
    methods="${methods}|__truediv__|__xor__"

    # built-in exceptions https://docs.python.org/3/library/exceptions.html
    exceptions="ArithmeticError|AssertionError|AttributeError|BaseException|BlockingIOError"
    exceptions="${exceptions}|BrokenPipeError|BufferError|BytesWarning|ChildProcessError"
    exceptions="${exceptions}|ConnectionAbortedError|ConnectionError|ConnectionRefusedError"
    exceptions="${exceptions}|ConnectionResetError|DeprecationWarning|EOFError|Exception"
    exceptions="${exceptions}|FileExistsError|FileNotFoundError|FloatingPointError|FutureWarning"
    exceptions="${exceptions}|GeneratorExit|ImportError|ImportWarning|IndentationError"
    exceptions="${exceptions}|IndexError|InterruptedError|IsADirectoryError|KeyboardInterrupt"
    exceptions="${exceptions}|KeyError|LookupError|MemoryError|ModuleNotFoundError|NameError"
    exceptions="${exceptions}|NotADirectoryError|NotImplementedError|OSError|OverflowError"
    exceptions="${exceptions}|PendingDeprecationWarning|PermissionError|ProcessLookupError"
    exceptions="${exceptions}|RecursionError|ReferenceError|ResourceWarning|RuntimeError"
    exceptions="${exceptions}|RuntimeWarning|StopAsyncIteration|StopIteration|SyntaxError"
    exceptions="${exceptions}|SyntaxWarning|SystemError|SystemExit|TabError|TimeoutError|TypeError"
    exceptions="${exceptions}|UnboundLocalError|UnicodeDecodeError|UnicodeEncodeError|UnicodeError"
    exceptions="${exceptions}|UnicodeTranslateError|UnicodeWarning|UserWarning|ValueError|Warning"
    exceptions="${exceptions}|ZeroDivisionError"

    # Keyword list is collected using `keyword.kwlist` from `keyword`
    keywords="and|as|assert|break|class|continue|def|del|elif|else|except|exec"
    keywords="${keywords}|finally|for|global|if|in|is|lambda|not|or|pass|print"
    keywords="${keywords}|raise|return|try|while|with|yield"

    types="bool|buffer|bytearray|bytes|complex|dict|file|float|frozenset|int"
    types="${types}|list|long|memoryview|object|set|str|tuple|unicode|xrange"

    functions="abs|all|any|ascii|bin|callable|chr|classmethod|compile|complex"
    functions="${functions}|delattr|dict|dir|divmod|enumerate|eval|exec|filter"
    functions="${functions}|format|frozenset|getattr|globals|hasattr|hash|help"
    functions="${functions}|hex|id|__import__|input|isinstance|issubclass|iter"
    functions="${functions}|len|locals|map|max|memoryview|min|next|oct|open|ord"
    functions="${functions}|pow|print|property|range|repr|reversed|round"
    functions="${functions}|setattr|slice|sorted|staticmethod|sum|super|type|vars|zip"

    # Add the language's grammar to the static completion list
    printf %s\\n "hook global WinSetOption filetype=python %{
        set-option window static_words '${values}:${meta}:${attributes}:${methods}:${exceptions}:${keywords}:${types}:${functions}'
    }" | tr '|' ':'

    # Highlight keywords
    printf %s "
        add-highlighter shared/python/code regex '\b(${values})\b' 0:value
        add-highlighter shared/python/code regex '\b(${meta})\b' 0:meta
        add-highlighter shared/python/code regex '\b(${attribute})\b' 0:attribute
        add-highlighter shared/python/code regex '\bdef\s+(${methods})\b' 1:function
        add-highlighter shared/python/code regex '\b(${exceptions})\b' 0:function
        add-highlighter shared/python/code regex '\b(${keywords})\b' 0:keyword
        add-highlighter shared/python/code regex '\b(${functions})\b\(' 1:builtin
        add-highlighter shared/python/code regex '\b(${types})\b' 0:type
        add-highlighter shared/python/code regex '@[\w_]+\b' 0:attribute
    "
}

add-highlighter shared/python/code regex (?<=[\w\s\d'"_])(<=|<<|>>|>=|<>|<|>|!=|==|\||\^|&|\+|-|\*\*|\*|//|/|%|~) 0:operator
add-highlighter shared/python/code regex (?<=[\w\s\d'"_])((?<![=<>!])=(?![=])|[+*-]=) 0:builtin

# Commands
# ‾‾‾‾‾‾‾‾

define-command -hidden python-indent-on-new-line %{
    evaluate-commands -draft -itersel %{
        # copy '#' comment prefix and following white spaces
        try %{ execute-keys -draft k <a-x> s ^\h*#\h* <ret> y jgh P }
        # preserve previous line indent
        try %{ execute-keys -draft \; K <a-&> }
        # cleanup trailing whitespaces from previous line
        try %{ execute-keys -draft k <a-x> s \h+$ <ret> d }
        # indent after line ending with :
        try %{ execute-keys -draft <space> k x <a-k> :$ <ret> j <a-gt> }
    }
}

# Initialization
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾

hook -group python-highlight global WinSetOption filetype=python %{ add-highlighter window ref python }

hook global WinSetOption filetype=python %{
    hook window InsertChar \n -group python-indent python-indent-on-new-line
    # cleanup trailing whitespaces on current line insert end
    hook window ModeChange insert:.* -group python-indent %{ try %{ execute-keys -draft \; <a-x> s ^\h+$ <ret> d } }
}

hook -group python-highlight global WinSetOption filetype=(?!python).* %{ remove-highlighter window/python }

hook global WinSetOption filetype=(?!python).* %{
    remove-hooks window python-indent
}