kakoune/rc/filetype/python.kak
2023-04-02 21:09:57 +09:00

200 lines
9.8 KiB
Plaintext

# http://python.org
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
# Detection
# ‾‾‾‾‾‾‾‾‾
hook global BufCreate .*[.](py) %{
set-option buffer filetype python
}
# Initialization
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾
hook global WinSetOption filetype=python %{
require-module python
set-option window static_words %opt{python_static_words}
hook window InsertChar \n -group python-insert python-insert-on-new-line
hook window InsertChar \n -group python-indent python-indent-on-new-line
# cleanup trailing whitespaces on current line insert end
hook window ModeChange pop:insert:.* -group python-trim-indent %{ try %{ execute-keys -draft <semicolon> x s ^\h+$ <ret> d } }
hook -once -always window WinSetOption filetype=.* %{ remove-hooks window python-.+ }
}
hook -group python-highlight global WinSetOption filetype=python %{
add-highlighter window/python ref python
hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/python }
}
provide-module python %§
# Highlighters & Completion
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
add-highlighter shared/python regions
add-highlighter shared/python/code default-region group
add-highlighter shared/python/docstring region -match-capture ^\h*("""|''') (?<!\\)(?:\\\\)*("""|''') regions
add-highlighter shared/python/documentation region '##' '$' fill documentation
add-highlighter shared/python/comment region '#' '$' fill comment
# String interpolation
add-highlighter shared/python/f_triple_string region -match-capture [fF]("""|''') (?<!\\)(?:\\\\)*("""|''') group
add-highlighter shared/python/f_triple_string/ fill string
add-highlighter shared/python/f_triple_string/ regex \{.*?\} 0:value
add-highlighter shared/python/f_double_string region '[fF]"' (?<!\\)(\\\\)*" group
add-highlighter shared/python/f_double_string/ fill string
add-highlighter shared/python/f_double_string/ regex \{.*?\} 0:value
add-highlighter shared/python/f_single_string region "[fF]'" (?<!\\)(\\\\)*' group
add-highlighter shared/python/f_single_string/ fill string
add-highlighter shared/python/f_single_string/ regex \{.*?\} 0:value
# Regular string
add-highlighter shared/python/triple_string region -match-capture ("""|''') (?<!\\)(?:\\\\)*("""|''') fill string
add-highlighter shared/python/double_string region '"' (?<!\\)(\\\\)*" fill string
add-highlighter shared/python/single_string region "'" (?<!\\)(\\\\)*' fill string
# 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/docstring/ default-region fill documentation
add-highlighter shared/python/docstring/ region '(>>>|\.\.\.) \K' (?=''')|(?=""") ref python
evaluate-commands %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__
__globals__ __kwdefaults__ __module__ __name__ __qualname__"
methods="__abs__ __add__ __aenter__ __aexit__ __aiter__ __and__ __anext__
__await__ __bool__ __bytes__ __call__ __complex__ __contains__
__del__ __delattr__ __delete__ __delitem__ __dir__ __divmod__
__enter__ __eq__ __exit__ __float__ __floordiv__ __format__
__ge__ __get__ __getattr__ __getattribute__ __getitem__
__gt__ __hash__ __iadd__ __iand__ __ifloordiv__ __ilshift__
__imatmul__ __imod__ __imul__ __index__ __init__
__init_subclass__ __int__ __invert__ __ior__ __ipow__
__irshift__ __isub__ __iter__ __itruediv__ __ixor__ __le__
__len__ __length_hint__ __lshift__ __lt__ __matmul__
__missing__ __mod__ __mul__ __ne__ __neg__ __new__ __or__
__pos__ __pow__ __radd__ __rand__ __rdivmod__ __repr__
__reversed__ __rfloordiv__ __rlshift__ __rmatmul__ __rmod__
__rmul__ __ror__ __round__ __rpow__ __rrshift__ __rshift__
__rsub__ __rtruediv__ __rxor__ __set__ __setattr__
__setitem__ __set_name__ __slots__ __str__ __sub__
__truediv__ __xor__"
# built-in exceptions https://docs.python.org/3/library/exceptions.html
exceptions="ArithmeticError AssertionError AttributeError BaseException BlockingIOError
BrokenPipeError BufferError BytesWarning ChildProcessError
ConnectionAbortedError ConnectionError ConnectionRefusedError
ConnectionResetError DeprecationWarning EOFError Exception
FileExistsError FileNotFoundError FloatingPointError FutureWarning
GeneratorExit ImportError ImportWarning IndentationError
IndexError InterruptedError IsADirectoryError KeyboardInterrupt
KeyError LookupError MemoryError ModuleNotFoundError NameError
NotADirectoryError NotImplementedError OSError OverflowError
PendingDeprecationWarning PermissionError ProcessLookupError
RecursionError ReferenceError ResourceWarning RuntimeError
RuntimeWarning StopAsyncIteration StopIteration SyntaxError
SyntaxWarning SystemError SystemExit TabError TimeoutError TypeError
UnboundLocalError UnicodeDecodeError UnicodeEncodeError UnicodeError
UnicodeTranslateError UnicodeWarning UserWarning ValueError Warning
ZeroDivisionError"
# Keyword list is collected using `keyword.kwlist` from `keyword`
keywords="and as assert async await break class continue def del elif else except exec
finally for global if in is lambda nonlocal not or pass print
raise return try while with yield"
# Collected from `keyword.softkwlist`
soft_keywords="_ case match"
types="bool buffer bytearray bytes complex dict file float frozenset int
list long memoryview object set str tuple unicode xrange"
functions="abs all any ascii bin breakpoint callable chr classmethod compile complex
delattr dict dir divmod enumerate eval exec filter
format frozenset getattr globals hasattr hash help
hex id __import__ input isinstance issubclass iter
len locals map max memoryview min next oct open ord
pow print property range repr reversed round
setattr slice sorted staticmethod sum super type vars zip"
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 python_static_words $(join "${values} ${meta} ${attributes} ${methods} ${exceptions} ${keywords} ${types} ${functions}" ' ')"
# Highlight keywords
printf %s "
add-highlighter shared/python/code/ regex '\b($(join "${values}" '|'))\b' 0:value
add-highlighter shared/python/code/ regex '\b($(join "${meta}" '|'))\b' 0:meta
add-highlighter shared/python/code/ regex '\b($(join "${attributes}" '|'))\b' 0:attribute
add-highlighter shared/python/code/ regex '\bdef\s+($(join "${methods}" '|'))\b' 1:function
add-highlighter shared/python/code/ regex '\b($(join "${exceptions}" '|'))\b' 0:function
add-highlighter shared/python/code/ regex '\b($(join "${keywords} ${soft_keywords}" '|'))\b' 0:keyword
add-highlighter shared/python/code/ regex '\b($(join "${functions}" '|'))\b\(' 1:builtin
add-highlighter shared/python/code/ regex '\b($(join "${types}" '|'))\b' 0:type
add-highlighter shared/python/code/ regex '^\h*(@[\w_.]+))' 1:attribute
"
}
add-highlighter shared/python/code/ regex (?<=[\w\s\d\)\]'"_])(<=|<<|>>|>=|<>?|>|!=|==|\||\^|&|\+|-|\*\*?|//?|%|~) 0:operator
add-highlighter shared/python/code/ regex (?<=[\w\s\d'"_])((?<![=<>!]):?=(?![=])|[+*-]=) 0:builtin
add-highlighter shared/python/code/ regex ^\h*(?:from|import)\h+(\S+) 1:module
# Commands
# ‾‾‾‾‾‾‾‾
define-command -hidden python-insert-on-new-line %{ evaluate-commands -itersel -draft %{
execute-keys <semicolon>
try %{
evaluate-commands -draft -save-regs '/"' %{
# copy the commenting prefix
execute-keys -save-regs '' k x1s^\h*(#+\h*)<ret> y
try %{
# if the previous comment isn't empty, create a new one
execute-keys x<a-K>^\h*#+\h*$<ret> jxs^\h*<ret>P
} catch %{
# if there is no text in the previous comment, remove it completely
execute-keys d
}
}
# trim trailing whitespace on the previous line
try %{ execute-keys -draft k x s\h+$<ret> d }
}
} }
define-command -hidden python-indent-on-new-line %<
evaluate-commands -draft -itersel %<
# preserve previous line indent
try %{ execute-keys -draft <semicolon> K <a-&> }
# cleanup trailing whitespaces from previous line
try %{ execute-keys -draft k x s \h+$ <ret> d }
# indent after line ending with :
try %{ execute-keys -draft , k x <a-k> :$ <ret> <a-K> ^\h*# <ret> j <a-gt> }
# deindent closing brace/bracket when after cursor (for arrays and dictionaries)
try %< execute-keys -draft x <a-k> ^\h*[}\]] <ret> gh / [}\]] <ret> m <a-S> 1<a-&> >
>
>
§