diff --git a/profiles/base/.aliases b/profiles/base/.aliases index c506aaa..8dc142f 100644 --- a/profiles/base/.aliases +++ b/profiles/base/.aliases @@ -17,4 +17,4 @@ alias scancel="ssh lcluster11 scancel" # faster sshfs #alias sshfs="sshfs -o Ciphers=arcfour,Compression=no,auto_cache" -alias sshfs="sshfs -o Compression=no,auto_cache" +#alias sshfs="sshfs -o Compression=no,auto_cache" diff --git a/profiles/base/.config/matplotlib/matplotlibrc b/profiles/base/.config/matplotlib/matplotlibrc index c1d479d..dbefca6 100644 --- a/profiles/base/.config/matplotlib/matplotlibrc +++ b/profiles/base/.config/matplotlib/matplotlibrc @@ -286,7 +286,7 @@ axes.edgecolor : black # axes edge color axes.grid : True # display grid or not #axes.titlesize : large # fontsize of the axes title #axes.titlepad : 6.0 # pad between axes and title in points -#axes.labelsize : medium # fontsize of the x any y labels +axes.labelsize : 16 #medium # fontsize of the x any y labels #axes.labelpad : 4.0 # space between label and axis #axes.labelweight : normal # weight of the x and y labels axes.labelcolor : black @@ -315,8 +315,8 @@ axes.labelcolor : black axes.spines.left : True # display axis spines axes.spines.bottom : True -axes.spines.top : True -axes.spines.right : True +axes.spines.top : False +axes.spines.right : False #axes.unicode_minus : True # use unicode for the minus symbol @@ -344,16 +344,16 @@ axes.ymargin : .00 # y margin See `axes.Axes.margins` #xtick.minor.size : 10 # minor tick size in points xtick.major.pad : 6 # distance to major tick label in points xtick.minor.pad : 6 # distance to the minor tick label in points -xtick.color : 797979 # color of the tick labels -#xtick.labelsize : medium # fontsize of the tick labels +xtick.color : 000000 #797979 # color of the tick labels +xtick.labelsize : 16# medium # fontsize of the tick labels xtick.direction : out # direction: in or out #ytick.major.size : 0 # major tick size in points #ytick.minor.size : 0 # minor tick size in points ytick.major.pad : 6 # distance to major tick label in points ytick.minor.pad : 6 # distance to the minor tick label in points -ytick.color : 797979 # color of the tick labels -#ytick.labelsize : medium # fontsize of the tick labels +ytick.color : 000000 #797979 # color of the tick labels +ytick.labelsize : 16 #medium # fontsize of the tick labels ytick.direction : out # direction: in or out @@ -389,7 +389,7 @@ legend.fontsize : 8 # 10 # See http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure #figure.titlesize : large # size of the figure title (Figure.suptitle()) #figure.titleweight : normal # weight of the figure title -figure.figsize : 11,4.5 # figure size in inches +figure.figsize : 6.4,4.8 # figure size in inches figure.dpi : 300 # figure dots per inch #figure.facecolor : yellow #white # figure facecolor; 0.75 is scalar gray # figure.edgecolor : white # figure edgecolor @@ -468,7 +468,7 @@ scatter.marker : o # The default marker type for scatter plots. # the default savefig params can be different from the display params # e.g., you may want a higher resolution, or to make the figure # background white -#savefig.dpi : figure # figure dots per inch or 'figure' +savefig.dpi : 300 # figure dots per inch or 'figure' #savefig.facecolor : white # figure facecolor when saving #savefig.edgecolor : white # figure edgecolor when saving #savefig.format : png # png, ps, pdf, svg diff --git a/profiles/base/.gitconfig b/profiles/base/.gitconfig index 75019e3..7b89570 100644 --- a/profiles/base/.gitconfig +++ b/profiles/base/.gitconfig @@ -1,7 +1,8 @@ # This is Git's per-user configuration file. [user] # Please adapt and uncomment the following lines: - name = Daniel Bauer + name = daniel + email = bauer@cbs.tu-darmstadt.de [pack] threads = 8 [merge] diff --git a/profiles/base/.vimrc b/profiles/base/.vimrc index 4ad9e4a..d18c956 100644 --- a/profiles/base/.vimrc +++ b/profiles/base/.vimrc @@ -29,6 +29,9 @@ Plugin 'Yggdroot/indentLine' Plugin 'godlygeek/tabular' Plugin 'plasticboy/vim-markdown' Plugin 'morhetz/gruvbox' +Plugin 'jpalardy/vim-slime' +let g:slime_target = "x11" + let g:vim_markdown_folding_disabled = 1 let g:pymode_python = "python3" diff --git a/profiles/base/.zshrc b/profiles/base/.zshrc index 8659e27..fdb18eb 100644 --- a/profiles/base/.zshrc +++ b/profiles/base/.zshrc @@ -19,7 +19,7 @@ else if [ -f "/home/bauer/conda/etc/profile.d/conda.sh" ]; then . "/home/bauer/conda/etc/profile.d/conda.sh" else - export PATH="$PATH:/home/bauer/conda/bin" + export PATH="/home/bauer/conda/bin:$PATH" fi fi unset __conda_setup diff --git a/profiles/laptop/.config/polybar/config b/profiles/laptop/.config/polybar/config index 683489d..47ce559 100644 --- a/profiles/laptop/.config/polybar/config +++ b/profiles/laptop/.config/polybar/config @@ -9,9 +9,9 @@ inherit = bar/base monitor = ${env:MONITOR:eDP-1} modules-left = i3 xwindow -modules-right = previous playpause next spotify volume cpu memory battery1 date +modules-right = previous playpause next spotify pulseaudio cpu memory battery1 date [bar/laptop_extern] inherit = bar/laptop -monitor = ${env:MONITOR:HDMI-2} \ No newline at end of file +monitor = ${env:MONITOR:HDMI-2} diff --git a/profiles/pymol/.pymolrc b/profiles/pymol/.pymolrc index fad2107..f228fff 100644 --- a/profiles/pymol/.pymolrc +++ b/profiles/pymol/.pymolrc @@ -61,5 +61,8 @@ set_key F12, ray 1600,1600 alias clean, hide everything, hydrogen or n. 1M* or n. 2M* or n. MC* -alias sf_as_sticks, show sticks, residue 478-484 and (not hydrogen or (hydrogen and neighbor (elem O+N+S))) and not (n. 1M* or n. 2M* or n. MC*); hide cartoon, resi 479-483; show sticks, residue 475+468 and (not hydrogen or (hydrogen and neighbor (elem O+N+S))) and not (n. 1M* or n. 2M* or n. MC*) +alias sf_as_sticks_HCN4, show sticks, residue 478-484 and (not hydrogen or (hydrogen and neighbor (elem O+N+S))) and not (n. 1M* or n. 2M* or n. MC*); hide cartoon, resi 479-483; show sticks, residue 475+468 and (not hydrogen or (hydrogen and neighbor (elem O+N+S))) and not (n. 1M* or n. 2M* or n. MC*) + +alias sf_as_sticks_HCN1, show sticks, residue 357-362 and (not hydrogen or (hydrogen and neighbor (elem O+N+S))) and not (n. 1M* or n. 2M* or n. MC*); hide cartoon, resi 358-361 + alias dockfix, as sticks, bonded and not polymer diff --git a/profiles/shared/.config/i3/config b/profiles/shared/.config/i3/config index 4519867..bd24af3 100644 --- a/profiles/shared/.config/i3/config +++ b/profiles/shared/.config/i3/config @@ -123,6 +123,7 @@ bindsym $mod+6 workspace $workspace6 bindsym $mod+7 workspace $workspace7 bindsym $mod+8 workspace $workspace8 bindsym $mod+9 workspace $workspace9 +bindsym $mod+0 workspace $workspace10 # move focused container to workspace bindsym $mod+Shift+1 move container to workspace $workspace1 @@ -134,6 +135,7 @@ bindsym $mod+Shift+6 move container to workspace $workspace6 bindsym $mod+Shift+7 move container to workspace $workspace7 bindsym $mod+Shift+8 move container to workspace $workspace8 bindsym $mod+Shift+9 move container to workspace $workspace9 +bindsym $mod+Shift+0 move container to workspace $workspace10 # reload the configuration file bindsym $mod+Shift+c reload @@ -181,9 +183,26 @@ new_window 1pixel exec_always --no-startup-id ~/.config/polybar/polybar.sh + +# "special" workspaces +# workspace7 => zotero +# worksapce8 => chat +# workspace9 => emailing +# workspace0 => music workspace $workspace7 output DP-0 +assign [class="Zotero"] → $workspace7 +assign [class="Mendeley"] → $workspace7 + workspace $workspace8 output DP-0 +assign [class="Skype" title="Skype"] → $workspace8 +assign [class="Mattermost" instance="mattermost"] → $workspace8 + workspace $workspace9 output DP-0 +assign [class="thunderbird"] → $workspace9 + +workspace $workspace10 output DP-0 +for_window [class="Spotify"] move to workspace $workspace10 +assign [class="Spotify"] → $workspace10 for_window [window_role="pop-up"] floating enable for_window [class="Chromium" window_role="pop-up"] floating disable @@ -193,24 +212,16 @@ for_window [class="Toplevel"] floating enable for_window [title="VMD*"] floating enable for_window [title="Area per Lipid*"] floating enable for_window [title="MEMBPLUGIN"] floating enable -for_window [title="Figure*"] floating enable +#for_window [title="Figure*"] floating enable for_window [window_role="conversation" class="Pidgin"] floating enable -for_window [class="Spotify"] move to workspace $workspace8 -assign [class="Thunderbird"] → $workspace9 -assign [class="Mendeley"] → $workspace7 -#assign [class="Spotify"] → $workspace8 -assign [title="Buddy List"] → $workspace9 exec --no-startup-id thunderbird -#exec --no-startup-id mendeleydesktop -#exec --no-startup-id spotify -#exec --no-startup-id pidgin exec feh --bg-scale ~/wallpaper.jpg #exec volumeicon exec thunar --daemon -exec --no-startup-id xautolock -time 5 -locker 'i3lock -i ~/.lockscreen/`ls /home/bauer/lockscreens | shuf -n 1` -t -f' +#exec --no-startup-id xautolock -time 5 -locker 'i3lock -i ~/.lockscreen/`ls /home/bauer/lockscreens | shuf -n 1` -t -f' # Pulse Audio controls bindsym --release XF86AudioLowerVolume exec --no-startup-id amixer sset Master 5%- #decrease sound volume @@ -236,6 +247,9 @@ bindsym $mod+Shift+s exec --no-startup-id ~/.config/i3/scripts/change_monitor.sh # reload workspace layouts #exec --no-startup-id "i3-msg 'workspace 9; append_layout /home/bauer/.i3/workspace-9.json'" +exec --no-startup-id skypeforlinux +exec --no-startup-id mattermost-desktop +exec --no-startup-id nextcloud exec --no-startup-id nm-applet exec --no-startup-id xfsettingsd --sm-client-disable & exec --no-startup-id /usr/bin/blueman-applet diff --git a/profiles/shared/.config/polybar/config.d/modules b/profiles/shared/.config/polybar/config.d/modules index 5a76ddf..1f817c6 100644 --- a/profiles/shared/.config/polybar/config.d/modules +++ b/profiles/shared/.config/polybar/config.d/modules @@ -85,9 +85,10 @@ ws-icon-2=3;3 ws-icon-3=4;4 ws-icon-4=5;5 ws-icon-5=6;6 -ws-icon-6=7; -ws-icon-7=8; +ws-icon-6=7; +ws-icon-7=8; ws-icon-8=9; +ws-icon-9=10; [module/mpd] type=internal/mpd diff --git a/profiles/shared/.config/sublime-text-3/Packages/User/Package Control.sublime-settings b/profiles/shared/.config/sublime-text-3/Packages/User/Package Control.sublime-settings index 7b9e021..b1b8834 100644 --- a/profiles/shared/.config/sublime-text-3/Packages/User/Package Control.sublime-settings +++ b/profiles/shared/.config/sublime-text-3/Packages/User/Package Control.sublime-settings @@ -9,12 +9,14 @@ "Color Highlight", "ColorPicker", "CWL Syntax Highlighting", + "Fortran", "gruvbox", "Helium", "Incomprehensible Ex", "LaTeX Snippets", "LaTeXTools", "LSP", + "MarkdownLivePreview", "MarkdownPreview", "NeoVintageous", "Package Control", @@ -23,6 +25,7 @@ "Rust Enhanced", "SideBarEnhancements", "TabNine", + "Thesaurus", "WordCount" ] } diff --git a/profiles/shared/.config/sublime-text-3/Packages/User/Preferences.sublime-settings b/profiles/shared/.config/sublime-text-3/Packages/User/Preferences.sublime-settings index 7e13c6d..6dfbb5f 100644 --- a/profiles/shared/.config/sublime-text-3/Packages/User/Preferences.sublime-settings +++ b/profiles/shared/.config/sublime-text-3/Packages/User/Preferences.sublime-settings @@ -1,10 +1,18 @@ { + "added_words": + [ + "subprojects", + "equimolar", + "transmembrane", + "Lichtenberg", + "Gromacs" + ], "auto_complete": false, "color_scheme": "Packages/gruvbox/gruvbox (Dark) (Medium).sublime-color-scheme", "detect_indentation": false, "dictionary": "Packages/Language - English/en_US.dic", "font_face": "Hack for Powerline Regular", - "font_size": 14, + "font_size": 12, "hot_exit": false, "ignored_packages": [ diff --git a/profiles/shared/.config/sublime-text-3/Packages/User/snakemake.sublime-syntax b/profiles/shared/.config/sublime-text-3/Packages/User/snakemake.sublime-syntax new file mode 100644 index 0000000..ac04c18 --- /dev/null +++ b/profiles/shared/.config/sublime-text-3/Packages/User/snakemake.sublime-syntax @@ -0,0 +1,2142 @@ +%YAML 1.2 +--- +name: Snakemake +file_extensions: + - smk + - rules + - snake +first_line_match: ^#!\s*/.*\bpython(\d(\.\d)?)?\b +scope: source.python + +variables: + # We support unicode here because Python 3 is the future + identifier_continue: '[[:alnum:]_]' + identifier: '\b[[:alpha:]_]{{identifier_continue}}*\b' + identifier_constant: '\b(?:[\p{Lu}_][\p{Lu}_\d]*)?[\p{Lu}]{2,}[\p{Lu}_\d]*\b' # require 2 consecutive upper-case letters + digitpart: (?:\d(?:_?\d)*) + path: '({{identifier}}[ ]*\.[ ]*)*{{identifier}}' + sql_indicator: \s*(?:SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER|WITH)\b + illegal_names: (?:and|as|assert|break|class|continue|def|del|elif|else|except|finally|for|from|global|if|import|in|is|lambda|not|or|pass|raise|return|try|while|with|yield) + format_spec: |- + (?x: + (?:.? [<>=^])? # fill align + [ +-]? # sign + \#? # alternate form + # technically, octal and hexadecimal integers are also supported as 'width', but rarely used + \d* # width + ,? # thousands separator + (?:\.\d+)? # precision + [bcdeEfFgGnosxX%]? # type + ) + strftime_spec: '(?:%(?:[aAwdbBGmyYHIpMSfzZjuUVWcxX%]|-[dmHIMSj]))' + # This can be used in look-aheads to parse simple expressions. + # Can't be recursive, because sregex doesn't support that, + # so we're skipping parentheses. + # Can't parse multiple lines as well, for obvious reasons + simple_expression: |- + (?x: + \s+ # whitespace + | [urfb]*"(?:\\.|[^"])*" # strings + | [urfb]*'(?:\\.|[^'])*' # ^ + | [\d.ej]+ # numerics + | [+*/%@-] | // | and | or # operators + | {{path}} # a path + )* +contexts: + main: + - include: statements + + statements: + - include: docstrings + - include: line-statements + - include: block-statements + - include: classes + - include: functions + - include: modifiers + - include: assignments + - match: ; + scope: punctuation.terminator.statement.python + - include: line-expressions + + line-statements: + - include: imports + - include: decorators + - match: \b(raise)\b + scope: keyword.control.flow.raise.python + push: + - meta_scope: meta.statement.raise.python + - include: line-continuation-or-pop + - match: \b(from)\b + scope: keyword.control.flow.raise.from.python + set: + - meta_scope: meta.statement.raise.python + - include: line-continuation-or-pop + - include: expressions + - include: expressions + - match: \b(assert)\b + scope: keyword.other.assert.python + - match: \b(del)\b + scope: keyword.other.del.python + - match: \b(print)\b(?! *([,.()\]}])) + scope: keyword.other.print.python + - match: \b(exec)\b(?! *($|[,.()\]}])) + scope: keyword.other.exec.python + - match: \b(return)\b + scope: keyword.control.flow.return.python + - match: \b(break)\b + scope: keyword.control.flow.break.python + - match: \b(continue)\b + scope: keyword.control.flow.continue.python + - match: \b(pass)\b + scope: keyword.control.flow.pass.python + - match: ':' + scope: punctuation.separator.annotation.variable.python + + imports: + - match: \b(import)\b + scope: keyword.control.import.python + push: + - meta_scope: meta.statement.import.python + - include: line-continuation-or-pop + - match: ',' + scope: punctuation.separator.import-list.python + - match: \. + scope: invalid.illegal.unexpected-relative-import.python + - include: import-alias + - include: qualified-name + - match: (?=\S) + pop: true + - match: \b(from)\b + scope: keyword.control.import.from.python + push: + - meta_scope: meta.statement.import.python + - meta_content_scope: meta.import-source.python + - include: line-continuation-or-pop + - match: \b(import)\b + scope: keyword.control.import.python + set: + - meta_scope: meta.statement.import.python + - include: line-continuation-or-pop + - match: ' *(\()' + captures: + 1: punctuation.section.import-list.begin.python + set: + - meta_scope: meta.statement.import.python + - include: comments + - match: \) + scope: punctuation.section.import-list.end.python + pop: true + - include: import-name-list + - match: (?=\S) + pop: true + - match: '' + set: + - meta_scope: meta.statement.import.python + - include: line-continuation-or-pop + - include: import-name-list + - match: (?=\S) + pop: true + - match: (?=\S) + pop: true + - include: import-from-name + - match: (?=\S) + pop: true + + import-name-list: + - match: ',' + scope: punctuation.separator.import-list.python + - include: import-alias + - include: name + - match: \* + scope: constant.language.import-all.python + - match: \S+ + scope: invalid.illegal.name.import.python + + import-alias: + - match: \b(as)\b + scope: keyword.control.import.as.python + + import-from-name: + - match: \.+ + scope: meta.import-path.python keyword.control.import.relative.python + - match: (?={{path}}) + push: + - meta_scope: meta.import-path.python + - match: '{{illegal_names}}\b' + scope: invalid.illegal.name.python + - match: '{{identifier}}' + scope: meta.import-name.python + - match: \s*(\.) *(?:({{illegal_names}}\b)|({{identifier}})) + captures: + 1: punctuation.accessor.dot.python + 2: invalid.illegal.name.python + 3: meta.import-name.python + - match: \ *(\. *\S+) # matches and consumes the remainder of "abc.123" or "abc.+" + captures: + 1: invalid.illegal.name.python + pop: true + - match: '' + pop: true + + block-statements: + # async for ... in ...: + - match: \b(async +)?(for)\b + captures: + 1: storage.modifier.async.python + 2: keyword.control.loop.for.python + push: + - meta_scope: meta.statement.loop.for.python + - include: line-continuation-or-pop + - match: \bin\b + scope: keyword.control.loop.for.in.python + set: + - meta_content_scope: meta.statement.loop.for.python + - include: line-continuation-or-pop + - match: ':' + scope: meta.statement.loop.for.python punctuation.section.block.loop.for.python + pop: true + - include: expressions + - match: ':' + scope: invalid.illegal.missing-in.python + pop: true + - include: target-list + # async with ... as ...: + - match: \b(async +)?(with)\b + captures: + 1: storage.modifier.async.python + 2: keyword.control.flow.with.python + push: with-body + # except ... as ...: + - match: \bexcept\b + scope: keyword.control.exception.catch.python + push: + - meta_scope: meta.statement.exception.catch.python + - include: line-continuation-or-pop + - match: ':' + scope: punctuation.section.block.exception.catch.python + pop: true + - match: '\bas\b' + scope: keyword.control.exception.catch.as.python + set: + - meta_content_scope: meta.statement.exception.catch.python + - include: line-continuation-or-pop + - match: ':' + scope: meta.statement.exception.catch.python punctuation.section.block.exception.catch.python + pop: true + - include: name + - include: target-list + - match: \bif\b + scope: keyword.control.conditional.if.python + push: + - meta_scope: meta.statement.conditional.if.python + - include: line-continuation-or-pop + - match: ':' + scope: punctuation.section.block.conditional.if.python + pop: true + - include: expressions + - match: \bwhile\b + scope: keyword.control.loop.while.python + push: + - meta_scope: meta.statement.loop.while.python + - include: line-continuation-or-pop + - match: ':' + scope: punctuation.section.block.loop.while.python + pop: true + - include: expressions + - match: \b(else)\b(?:\s*(:))? + scope: meta.statement.conditional.else.python + captures: + 1: keyword.control.conditional.else.python + 2: punctuation.section.block.conditional.else.python + - match: \b(try)\b(?:\s*(:))? + scope: meta.statement.exception.try.python + captures: + 1: keyword.control.exception.try.python + 2: punctuation.section.block.exception.try.python + - match: \b(finally)\b(?:\s*(:))? + scope: meta.statement.exception.finally.python + captures: + 1: keyword.control.exception.finally.python + 2: punctuation.section.block.exception.finally.python + - match: \belif\b + scope: keyword.control.conditional.elseif.python + push: + - meta_scope: meta.statement.conditional.elseif.python + - match: ':' + scope: punctuation.section.block.conditional.elseif.python + pop: true + - match: $\n? + pop: true + - include: line-expressions + + with-body: + - meta_scope: meta.statement.with.python + - include: line-continuation-or-pop + - match: \b(as)\b + scope: keyword.control.flow.with.as.python + set: with-as + - match: ':' + scope: punctuation.section.block.with.python + pop: true + - match: ',' + scope: punctuation.separator.with-resources.python + - include: expressions + + with-as: + - meta_scope: meta.statement.with.python + - include: line-continuation-or-pop + - match: ':' + scope: punctuation.section.block.with.python + pop: true + - match: ',' + scope: punctuation.separator.with-resources.python + set: with-body + - include: name + - include: groups + - include: lists + + expressions-common: + - include: comments + - include: constants + - include: numbers + - include: yields + - include: operators + - include: lambda + - match: \b(await)\b + scope: keyword.other.await.python + - include: inline-if + - include: strings + - include: function-calls + - include: item-access + - include: lists + - include: dictionaries-and-sets + - include: tuples + - include: groups + - match: \) + scope: invalid.illegal.stray.brace.round.python + - match: \] + scope: invalid.illegal.stray.brace.square.python + - match: \} + scope: invalid.illegal.stray.brace.curly.python + - include: line-continuation + + line-expressions: # Always include this last! + - include: expressions-common + - include: qualified-name + + expressions: # Always include this last! + # Differs from the line scope in that invalid-name matches will pop the current context + # and matches accessors continued on a different line + - include: expressions-common + - include: illegal-names-pop + - include: qualified-name + - match: '(\.) *(?={{identifier}})' + captures: + 1: punctuation.accessor.dot.python + push: + - include: magic-function-names + - include: magic-variable-names + - include: illegal-names + - include: generic-names + - match: '' + pop: true + + after-expression: + # direct function call + - match: '\s*(\()' + captures: + 1: punctuation.section.arguments.begin.python + push: + - meta_scope: meta.function-call.arguments.python + - match: \) + scope: punctuation.section.arguments.end.python + pop: true + - include: arguments + # item access + - match: '\s*(\[)' + captures: + 1: meta.item-access.python punctuation.section.brackets.begin.python + push: + - meta_content_scope: meta.item-access.arguments.python + - match: \] + scope: meta.item-access.python punctuation.section.brackets.end.python + pop: true + - match: ':' + scope: punctuation.separator.slice.python + - include: expressions + # indirect function call following attribute access + - include: function-calls + # arbitrary attribute access + - match: '\s*(\.)' + captures: + 1: punctuation.accessor.dot.python + push: + - include: magic-function-names + - include: magic-variable-names + - include: illegal-names + - include: generic-names + - match: '' + pop: true + - match: '' + pop: true + + comments: + - match: "#" + scope: punctuation.definition.comment.python + push: + - meta_scope: comment.line.number-sign.python + - match: \n + pop: true + + constants: + - match: \b(None|True|False|Ellipsis|NotImplemented|__debug__)\b + scope: constant.language.python + - match: \.{3}(?!\w) + scope: constant.language.python + + numbers: + # https://docs.python.org/3/reference/lexical_analysis.html#numeric-literals + # hexadecimal + - match: \b(?i)(0x)\h*(L) # py2 + scope: constant.numeric.integer.long.hexadecimal.python + captures: + 1: punctuation.definition.numeric.hexadecimal.python + 2: storage.type.numeric.long.python + - match: \b(?i)(0x)(_?\h)+ + scope: constant.numeric.integer.hexadecimal.python + captures: + 1: punctuation.definition.numeric.hexadecimal.python + # octal + - match: \b(?i)(0o?)(?=o|[0-7])[0-7]*(L) # py2 + scope: constant.numeric.integer.long.octal.python + captures: + 1: punctuation.definition.integer.octal.python + 2: storage.type.numeric.long.python + - match: \b(?i)(0)[0-7]+ # py2 + scope: constant.numeric.integer.octal.python + captures: + 1: punctuation.definition.numeric.octal.python + - match: \b(?i)(0o)(_?[0-7])+ + scope: constant.numeric.integer.octal.python + captures: + 1: punctuation.definition.numeric.octal.python + # binary + - match: \b(?i)(0b)[01]*(L) # py2 + scope: constant.numeric.integer.long.binary.python + captures: + 1: punctuation.definition.numeric.binary.python + 2: storage.type.numeric.long.python + - match: \b(?i)(0b)(_?[01])* + scope: constant.numeric.integer.binary.python + captures: + 1: punctuation.definition.numeric.binary.python + # complex + - match: (?i){{digitpart}}?(\.){{digitpart}}(?:e[\-\+]?{{digitpart}})?(j) # mandatory fraction + scope: constant.numeric.complex.python + captures: + 1: punctuation.separator.decimal.python + 2: storage.type.numeric.complex.python + - match: \b(?i)(?:{{digitpart}}(?:(\.){{digitpart}}?)?|(\.){{digitpart}})(?:e[\-\+]?{{digitpart}})(j) # mandatory exponent + scope: constant.numeric.complex.python + captures: + 1: punctuation.separator.decimal.python + 2: punctuation.separator.decimal.python + 3: storage.type.numeric.complex.python + - match: (?i){{digitpart}}(\.)?(j) # mandatory digitpart + scope: constant.numeric.complex.python + captures: + 1: punctuation.separator.decimal.python + 2: storage.type.numeric.complex.python + # floating point + - match: (?i){{digitpart}}?(\.){{digitpart}}(?:e[\-\+]?{{digitpart}})? # mandatory fraction + scope: constant.numeric.float.python + captures: + 1: punctuation.separator.decimal.python + - match: \b(?i)(?:{{digitpart}}(?:(\.){{digitpart}}?)?|(\.){{digitpart}})(?:e[\-\+]?{{digitpart}}) # mandatory exponent + scope: constant.numeric.float.python + captures: + 1: punctuation.separator.decimal.python + 2: punctuation.separator.decimal.python + - match: (?i){{digitpart}}(\.) # mandatory digitpart + scope: constant.numeric.float.python + captures: + 1: punctuation.separator.decimal.python + # integer + - match: \b(?i)(?:[1-9]\d*|0)(L)\b # py2 + scope: constant.numeric.integer.long.decimal.python + captures: + 1: storage.type.numeric.long.python + - match: \b(?i)([1-9][\d_]*|0)\b + scope: constant.numeric.integer.decimal.python + + modifiers: + - match: \b(?:(global)|(nonlocal))\b + captures: + 1: storage.modifier.global.python + 2: storage.modifier.nonlocal.python + push: + - include: line-continuation-or-pop + - match: ',' + scope: punctuation.separator.storage-list.python + - include: name + - match: \S+ + scope: invalid.illegal.name.storage.python + + yields: + - match: \b(yield)(?:\s+(from))?\b + captures: + 1: keyword.control.flow.yield.python + 2: keyword.control.flow.yield-from.python + + assignments: + - match: \+=|-=|\*=|/=|//=|%=|@=|&=|\|=|\^=|>>=|<<=|\*\*= + scope: keyword.operator.assignment.augmented.python + - match: '=(?!=)' + scope: keyword.operator.assignment.python + + operators: + - match: <> + scope: invalid.deprecated.operator.python + - match: <\=|>\=|\=\=|<|>|\!\= + scope: keyword.operator.comparison.python + - match: \+|\-|\*|\*\*|/|//|%|<<|>>|&|\||\^|~ + scope: keyword.operator.arithmetic.python + - match: \b(and|in|is|not|or)\b + comment: keyword operators that evaluate to True or False + scope: keyword.operator.logical.python + - match: '@' + scope: keyword.operator.matrix.python + + allow-unpack-operators: + # Match unpacking operators, if present + - include: comments + - match: \*{3,} + scope: invalid.illegal.syntax.python + pop: true + - match: \*\* + scope: keyword.operator.unpacking.mapping.python + pop: true + - match: \* + scope: keyword.operator.unpacking.sequence.python + pop: true + - match: (?=\S) + pop: true + + classes: + - match: '^\s*(class)\b' + captures: + 1: storage.type.class.python + push: + - meta_scope: meta.class.python + - include: line-continuation-or-pop + - match: ':' + scope: punctuation.section.class.begin.python + pop: true + - match: "(?={{identifier}})" + push: + - meta_content_scope: entity.name.class.python + - include: entity-name-class + - match: '' + pop: true + - match: \( + scope: punctuation.section.inheritance.begin.python + set: + - meta_scope: meta.class.inheritance.python + - match: \) + scope: punctuation.section.inheritance.end.python + set: + - include: line-continuation-or-pop + - match: ':' + scope: meta.class.python punctuation.section.class.begin.python + pop: true + - match: (?=\S) + pop: true + - match: ':' + scope: invalid.illegal.no-closing-parens.python + pop: true + - match: ',' + scope: punctuation.separator.inheritance.python + - include: illegal-names-pop + - match: ({{identifier}}) *(=) + captures: + 1: variable.parameter.class-inheritance.python + 2: keyword.operator.assignment.python + - match: (?={{path}}) + push: + - meta_scope: entity.other.inherited-class.python + - match: '{{identifier}}(?: *(\.) *)?' + captures: + 1: punctuation.accessor.dot.python + - match: '' + pop: true + - include: expressions + + functions: + - match: '^\s*(?:(async)\s+)?(def)\b' + captures: + 1: storage.modifier.async.python + 2: storage.type.function.python + push: + - meta_scope: meta.function.python + - include: line-continuation-or-pop + - match: ':' + scope: punctuation.section.function.begin.python + pop: true + - match: "(?={{identifier}})" + push: + - meta_content_scope: entity.name.function.python + - include: entity-name-function + - match: '' + pop: true + - match: '(?=\()' + set: + - match: \( + scope: meta.function.parameters.python punctuation.section.parameters.begin.python + set: [function-parameters, allow-unpack-operators] + + function-parameters: + - meta_content_scope: meta.function.parameters.python + - match: \) + scope: punctuation.section.parameters.end.python + set: function-after-parameters + - include: comments + - match: ',' + scope: punctuation.separator.parameters.python + push: allow-unpack-operators + - match: / + scope: storage.modifier.positional-args-only.python + push: + - match: (?=[,)]) + pop: true + - match: \S + scope: invalid.illegal.expected-comma.python + - match: '(?==)' + set: + - match: '=' + scope: keyword.operator.assignment.python + set: + - meta_scope: meta.function.parameters.default-value.python + - match: '(?=[,)])' + set: [function-parameters, allow-unpack-operators] + - include: expressions + - match: '(?=:)' + set: + - match: ':' + scope: punctuation.separator.annotation.parameter.python + set: + - meta_scope: meta.function.parameters.annotation.python + - match: '(?=[,)=])' + set: function-parameters + - include: expressions + - include: function-parameters-tuple + - include: illegal-names + - match: '{{identifier}}' + scope: variable.parameter.python + - include: line-continuation + + function-parameters-tuple: + # python 2 style tuple arguments + # removed from python 3 since PEP-3113 + - match: \( + scope: punctuation.section.group.begin.python + push: + - meta_scope: meta.group.python + - match: \) + scope: punctuation.section.group.end.python + set: after-expression + - include: comments + - match: ',' + scope: punctuation.separator.parameters.python + push: allow-unpack-operators + # default values should follow the argument + - match: '=' + push: + - meta_scope: invalid.illegal.default-value.python + - match: '(?=[,)=])' + pop: true + # python 2 does not support type annotations + - match: '(?=:)' + push: + - meta_scope: invalid.illegal.annotation.python + - match: '(?=[,)=])' + pop: true + - include: illegal-names + - match: '{{identifier}}' + scope: variable.parameter.python + - include: line-continuation + + function-after-parameters: + - meta_content_scope: meta.function.python + - match: '(?=->)' + set: + - meta_content_scope: meta.function.annotation.return.python + - match: -> + scope: punctuation.separator.annotation.return.python + - match: '(?=:)' + set: function-after-parameters + - include: line-continuation-or-pop + - include: expressions + - match: ':' + scope: meta.function.python punctuation.section.function.begin.python + pop: true + - include: comments + - match: (?=\S) + pop: true + + decorators: + - match: ^\s*(?=@) + push: + # Due to line continuations, we don't know whether this is a "function call" yet + - meta_content_scope: meta.annotation.python + - match: '@' + scope: punctuation.definition.annotation.python + - match: $ + pop: true + - include: line-continuation-or-pop + - match: (?=\.?\s*{{path}}\s*\() # now we do + set: [decorator-function-call-wrapper, qualified-name-until-leaf] + - match: (?=\.?\s*{{path}}) + push: [decorator-wrapper, qualified-name-until-leaf] + - match: \S + scope: invalid.illegal.character.python + pop: true + + decorator-wrapper: + - match: (\.)\s* + captures: + 1: punctuation.accessor.dot.python + set: + - meta_scope: meta.qualified-name.python + - meta_content_scope: variable.annotation.python + - include: dotted-name-specials + - include: generic-names + - match: '' + pop: true + - match: '' + set: + - meta_scope: meta.qualified-name.python variable.annotation.python + - include: name-specials + - include: generic-names + - match: '' + pop: true + + decorator-function-call-wrapper: + - meta_scope: meta.annotation.function.python + - match: \) + scope: punctuation.section.arguments.end.python + set: after-expression + - match: \( + scope: meta.annotation.function.python punctuation.section.arguments.begin.python + push: + - clear_scopes: 1 + - meta_content_scope: meta.annotation.arguments.python + - match: (?=\)) + pop: true + - include: arguments + - match: (\.)\s* + captures: + 1: punctuation.accessor.dot.python + push: + - meta_scope: meta.qualified-name.python + - meta_content_scope: variable.annotation.function.python + - include: dotted-name-specials + - include: generic-names + - match: '' + pop: true + - match: '' + push: + - meta_scope: meta.qualified-name.python variable.annotation.function.python + - include: name-specials + - include: generic-names + - match: '' + pop: true + + item-access: + - match: '(?={{path}}\s*\[)' + push: + - match: \] + scope: meta.item-access.python punctuation.section.brackets.end.python + set: after-expression + - match: '(?={{path}}\s*\[)' + push: + - meta_content_scope: meta.item-access.python + - match: '(?=\s*\[)' + pop: true + - include: qualified-name + - match: \[ + scope: meta.item-access.python punctuation.section.brackets.begin.python + push: + - meta_content_scope: meta.item-access.arguments.python + - match: '(?=\])' + pop: true + - match: ':' + scope: punctuation.separator.slice.python + - include: expressions + + function-calls: + - match: '(?=(\.\s*)?{{path}}\s*\()' + push: [function-call-wrapper, qualified-name-until-leaf] + + function-call-wrapper: + - meta_scope: meta.function-call.python + - match: (?=\() # need to remove meta.function-call.python from opening parens + set: + - match: \( + scope: punctuation.section.arguments.begin.python + set: + - meta_scope: meta.function-call.arguments.python + - match: \) + scope: punctuation.section.arguments.end.python + set: after-expression + - include: arguments + - match: (\.)\s*(?={{identifier}}) + captures: + 1: punctuation.accessor.dot.python + push: + - meta_scope: meta.qualified-name.python + - meta_content_scope: variable.function.python + - include: dotted-name-specials + - include: generic-names + - match: '' + pop: true + - match: (?={{identifier}}) + push: + - meta_scope: meta.qualified-name.python variable.function.python + - include: name-specials + - include: generic-names + - match: '' + pop: true + + arguments: + - include: keyword-arguments + - match: ',' + scope: punctuation.separator.arguments.python + push: allow-unpack-operators + - include: inline-for + - include: expressions + + keyword-arguments: + - match: '(?={{identifier}}\s*=(?!=))' + push: + - include: line-continuation-or-pop + - match: '=' + scope: keyword.operator.assignment.python + set: + - match: (?=\s*[,):]) + pop: true + - include: expressions + - include: illegal-names + - match: '{{identifier}}' + scope: variable.parameter.python + + lambda: + - match: \b(lambda)(?=\s|:|$) + scope: storage.type.function.inline.python + push: [lambda-parameters, allow-unpack-operators] + + lambda-parameters: + - meta_scope: meta.function.inline.python + - meta_content_scope: meta.function.inline.parameters.python + - include: line-continuation-or-pop + - match: '\:' + scope: punctuation.section.function.begin.python + pop: true + - match: ',' + scope: punctuation.separator.parameters.python + push: allow-unpack-operators + - include: keyword-arguments + - include: function-parameters-tuple + - include: illegal-names + - match: '{{identifier}}' + scope: variable.parameter.python + - match: '\S' + scope: invalid.illegal.expected-parameter.python + + groups: + - match: \( + scope: punctuation.section.group.begin.python + push: + - meta_scope: meta.group.python + - match: \) + scope: punctuation.section.group.end.python + set: after-expression + - match: ',' + scope: punctuation.separator.tuple.python + - include: inline-for + - include: expressions + + tuples: + # We don't know for certain, whether a parenthesized expression is a tuple, + # so try looking ahead. + - match: (\()\s*(\)) + scope: meta.sequence.tuple.empty.python + captures: + 1: punctuation.section.sequence.begin.python + 2: punctuation.section.sequence.end.python + push: after-expression + - match: \((?={{simple_expression}},|\s*\*{{path}}) + scope: punctuation.section.sequence.begin.python + push: inside-tuple + # TODO generator + # - match: \((?:{{simple_expression}}for) + + inside-tuple: + - meta_scope: meta.sequence.tuple.python + - match: \) + scope: punctuation.section.sequence.end.python + set: after-expression + - match: ',' + scope: punctuation.separator.sequence.python + push: allow-unpack-operators + - include: inline-for + - include: expressions + + lists: + - match: (\[)\s*(\]) + scope: meta.sequence.list.empty.python + captures: + 1: punctuation.section.sequence.begin.python + 2: punctuation.section.sequence.end.python + push: after-expression + - match: \[ + scope: punctuation.section.sequence.begin.python + push: [inside-list, allow-unpack-operators] + + inside-list: + - meta_scope: meta.sequence.list.python + - match: \] + scope: punctuation.section.sequence.end.python + set: after-expression + - match: ',' + scope: punctuation.separator.sequence.python + push: allow-unpack-operators + - include: inline-for + - include: expressions + + dictionaries-and-sets: + # Dictionaries and set literals use the same punctuation, + # so we try looking ahead to determine whether we have a dict or a set. + - match: '(\{)\s*(\})' + scope: meta.mapping.empty.python + captures: + 1: punctuation.section.mapping.begin.python + 2: punctuation.section.mapping.end.python + push: after-expression + - match: \{(?={{simple_expression}}:|\s*\*\*{{path}}) + scope: punctuation.section.mapping.begin.python + push: inside-dictionary + - match: \{(?={{simple_expression}}[,}]|\s*\*{{path}}) + scope: punctuation.section.set.begin.python + push: inside-set + # If the expression is "more complex" or on the next line, + # fall back to default and determine later. + - match: \{ + scope: punctuation.section.mapping-or-set.begin.python + push: + - meta_scope: meta.mapping-or-set.python + - match: \} + scope: punctuation.section.mapping-or-set.end.python + set: after-expression + - match: (?={{simple_expression}}:|\s*\*\*{{path}}) + set: inside-dictionary + - match: (?={{simple_expression}}[,}]|\s*\*{{path}}) + set: inside-set + - match: ',' + scope: punctuation.separator.set.python + set: inside-set + - match: ':' + scope: punctuation.separator.mapping.key-value.python + set: inside-directory-value + - include: inline-for + - include: expressions + + inside-dictionary: + - meta_scope: meta.mapping.python + - match: \} + scope: punctuation.section.mapping.end.python + set: after-expression + - match: ':' + scope: punctuation.separator.mapping.key-value.python + set: inside-directory-value + - match: ',' + scope: invalid.illegal.expected-colon.python + - match: \*\* + scope: keyword.operator.unpacking.mapping.python + push: + - match: (?=\}) + pop: true + - match: ',' + scope: punctuation.separator.mapping.python + pop: true + - include: expressions + - include: comments + - match: (?=\S) + push: + - clear_scopes: 1 + - meta_scope: meta.mapping.key.python + - match: \s*(?=\}|,|:) + pop: true + - include: expressions + + inside-directory-value: + - meta_content_scope: meta.mapping.python + - match: \} + scope: punctuation.section.mapping.end.python + set: after-expression + - match: (?=,) + set: + # clear meta scope from this match, because 'inside-directory' has it in meta_scope + - match: ',' + scope: punctuation.separator.mapping.python + set: inside-dictionary + - match: (?=for\b) + push: + - match: (?=\}) + pop: true + - match: ',' + scope: invalid.illegal.unexpected-comma.python + - include: inline-for + - include: expressions + - include: comments + - match: (?=\S) + push: + - clear_scopes: 1 + - meta_content_scope: meta.mapping.value.python + - match: (?=\s*(\}|,|for\b)) + pop: true + - include: expressions + + inside-set: + - meta_scope: meta.set.python + - match: \} + scope: punctuation.section.set.end.python + set: after-expression + - match: ':' + scope: invalid.illegal.colon-inside-set.python + - match: ',' + scope: punctuation.separator.set.python + - match: \* + scope: keyword.operator.unpacking.sequence.python + push: + - match: (?=\}) + pop: true + - match: ',' + scope: punctuation.separator.set.python + pop: true + - include: expressions + - include: inline-for + - include: expressions + + builtin-exceptions: + - match: |- + (?x)\b( + ( + Arithmetic|Assertion|Attribute|BlockingIO|BrokenPipe|Buffer|ChildProcess| + Connection(Aborted|Refused|Reset)?|EOF|Environment|FileExists| + FileNotFound|FloatingPoint|Interrupted|IO|IsADirectoryError| + Import|Indentation|Index|Key|Lookup|Memory|Name|NotADirectory| + NotImplemented|OS|Overflow|Permission|ProcessLookup|Reference| + Runtime|Standard|Syntax|System|Tab|Timeout|Type|UnboundLocal| + Unicode(Encode|Decode|Translate)?|Value|VMS|Windows|ZeroDivision + )Error| + ((Pending)?Deprecation|Runtime|Syntax|User|Future|Import|Unicode|Bytes)?Warning| + (Base)?Exception| + SystemExit|StopIteration|NotImplemented|KeyboardInterrupt|GeneratorExit + )\b + scope: support.type.exception.python + builtin-functions: + - match: |- + (?x)\b( + __import__|all|abs|any|apply|ascii|bin|breakpoint|callable|chr|classmethod|cmp|coerce| + compile|delattr|dir|divmod|enumerate|eval|exec|execfile|filter|format|getattr| + globals|hasattr|hash|help|hex|id|input|output|intern|isinstance|issubclass|iter| + len|locals|map|max|min|next|oct|open|ord|pow|print|property|range|shell|rule| + raw_input|reduce|reload|repr|reversed|round|setattr|sorted|staticmethod| + sum|super|type|unichr|vars|zip|include|workdir|ni|params|messsage|threads| + resources|version|run|singularity|conda|shadow|group|log + )\b + scope: support.function.builtin.python + builtin-types: + - match: |- + (?x)\b( + basestring|bool|buffer|bytearray|bytes|complex|dict|float|frozenset|int| + list|long|memoryview|object|range|set|slice|str|tuple|unicode|xrange + )\b + scope: support.type.python + name: + - match: '(?={{identifier}})' + push: + - include: name-specials + - match: '{{identifier_constant}}' + scope: variable.other.constant.python + - include: generic-names + - match: '' + pop: true + + dotted-name: + - match: '\s*(\.)\s*(?={{identifier}})' + captures: + 1: punctuation.accessor.dot.python + push: + - include: dotted-name-specials + - match: '{{identifier_constant}}' + scope: variable.other.constant.python + - include: generic-names + - match: '' + pop: true + + qualified-name: + - match: '(?={{path}})' + push: + - meta_scope: meta.qualified-name.python + - include: name + - include: dotted-name + - match: '' + pop: true + + qualified-name-until-leaf: + # Push this together with another context to match a qualified name + # until the last non-special identifier (if any). + # This allows the leaf to be scoped individually. + - meta_scope: meta.qualified-name.python + # If a line continuation follows, this may or may not be the last leaf (most likley not though) + - match: (?={{identifier}}\s*(\.|\\)) + push: + - include: name-specials + - include: generic-names + - match: '' + pop: true + - match: (\.)\s*(?={{identifier}}\s*(\.|\\)) + captures: + 1: punctuation.accessor.dot.python + push: + - include: dotted-name-specials + - include: generic-names + - match: '' + pop: true + - match: \.(?!\s*{{identifier}}) # don't match last dot + scope: punctuation.accessor.dot.python + - match: (?=\S|$) + pop: true + + name-specials: + - include: builtin-functions + - include: builtin-types + - include: builtin-exceptions + - include: illegal-names + - include: magic-function-names + - include: magic-variable-names + - include: language-variables + + dotted-name-specials: + - include: magic-function-names + - include: magic-variable-names + - include: illegal-names + + entity-name-class: + - include: illegal-names + - include: generic-names + + entity-name-function: + - include: magic-function-names + - include: illegal-names + - include: generic-names + + generic-names: + - match: '{{identifier}}' + scope: meta.generic-name.python + + illegal-names: + - match: \b{{illegal_names}}\b + scope: invalid.illegal.name.python + + illegal-names-pop: + - match: \b{{illegal_names}}\b + scope: invalid.illegal.name.python + pop: true + + language-variables: + - match: \b(self|cls)\b + scope: variable.language.python + - match: _(?!{{identifier_continue}}) + scope: variable.language.python + + line-continuation: + - match: (\\)(.*)$\n? + captures: + 1: punctuation.separator.continuation.line.python + 2: invalid.illegal.unexpected-text.python + # make sure to resume parsing at next line + push: + # This prevents strings after a continuation from being a docstring + - include: strings + - match: (?=\S|^\s*$|\n) # '\n' for when we matched a string earlier + pop: true + + line-continuation-or-pop: + - include: line-continuation + - match: (?=\s*($|;|#)) + pop: true + + magic-function-names: + # https://docs.python.org/2/reference/datamodel.html + # https://docs.python.org/3/reference/datamodel.html + - match: |- + (?x)\b__(?: + # unary operators + invert|neg|pos|abs| + # binary operators + add|and|div|divmod|floordiv|lshift|mod|mul|or|pow|rshift|sub|truediv|xor| + contains| + # right-hand binary operators + radd|rand|rdiv|rdivmod|rfloordiv|rlshift|rmod|rmul|ror|rpow|rrshift|rsub|rtruediv|rxor| + # in-place operator assignments + iadd|iand|idiv|ifloordiv|ilshift|imod|imul|ior|ipow|irshift|isub|itruediv|ixor| + # comparisons + eq|ge|gt|le|lt|ne| + cmp|rcmp| # py2 + # primary coercion + bool|str| + nonzero|unicode| # py2 + # number coercion (converts something to a number) + bytes|complex|float|index|int|round| + long| # py2 + # other "coercion" + format|len|length_hint|hash|repr|reversed| + coerce|hex|oct| # py2 + fspath| + # iterator (and 'await') + iter|next| + aiter|anext| + await| + # attribute and item access + delattr|delitem|delslice| + getattr|getattribute|getitem|getslice| + setattr|setitem|setslice| + dir|missing| + # context manager + enter|exit| + aenter|aexit| + # other class magic + call|del|init|new|init_subclass| + instancecheck|subclasscheck| + # pickling + getnewargs|getnewargs_ex|getstate|setstate|reduce|reduce_ex| + # descriptors + delete|get|set|set_name| + # class-specific + subclasses| + # dataclasses (PEP 557) + post_init| + # for typing core support (PEP 560) + class_getitem|mro_entries + )__\b + comment: these methods have magic interpretation by python and are generally called indirectly through syntactic constructs + scope: support.function.magic.python + magic-variable-names: + # magic variables which a class/module/object may have. + # https://docs.python.org/3/library/inspect.html#types-and-members + # https://docs.python.org/3/reference/datamodel.html#object.__slots__ + # https://docs.python.org/3/reference/datamodel.html#preparing-the-class-namespace + - match: |- + (?x)\b__(?: + # generic object + class|dict|doc|module|name| + # module-specific / global + all|file|package| + # functions & methods + annotations|closure|code|defaults|func|globals|kwdefaults|self|qualname| + # classes (attributes) + bases|prepare|slots|metaclass|mro| + # Python 2 + members|methods + )__\b + scope: support.variable.magic.python + # docstrings: + # - match: ^\s*(?=(?i)(ur|ru|u|r)?("""|''')) + # push: + # - match: (?i)(u)?("""|''') + # captures: + # 1: storage.type.string.python + # 2: punctuation.definition.comment.begin.python + # set: + # - meta_scope: comment.block.documentation.python + # - include: escaped-unicode-char + # - include: escaped-char + # - match: '\2' + # scope: punctuation.definition.comment.end.python + # pop: true + # - match: (?i)(u?ru?)("""|''') + # captures: + # 1: storage.type.string.python + # 2: punctuation.definition.comment.begin.python + # set: + # - meta_scope: comment.block.documentation.python + # - match: '\2' + # scope: punctuation.definition.comment.end.python + # pop: true + + escaped-char: + - match: '(\\x\h{2})|(\\[0-7]{1,3})|(\\[\\"''abfnrtv])' + captures: + 1: constant.character.escape.hex.python + 2: constant.character.escape.octal.python + 3: constant.character.escape.python + - match: \\. # deprecated in 3.6 and will eventually be a syntax error + scope: invalid.deprecated.character.escape.python + + escaped-unicode-char: + - match: '(\\U\h{8})|(\\u\h{4})|(\\N\{[a-zA-Z ]+\})' + captures: + 1: constant.character.escape.unicode.16-bit-hex.python + 2: constant.character.escape.unicode.32-bit-hex.python + 3: constant.character.escape.unicode.name.python + + escaped-fstring-escape: + # special-case the '\{{' sequence because it has higher priority than the deprecated '\{' + - match: (\\)(\{\{|\}\}) + scope: constant.character.escape.backslash.regexp + captures: + 1: invalid.deprecated.character.escape.python + 2: constant.character.escape.python + + line-continuation-inside-string: + - match: (\\)$\n? + captures: + 1: punctuation.separator.continuation.line.python + - match: \n + scope: invalid.illegal.unclosed-string.python + set: after-expression + + constant-placeholder: + - match: |- # printf style + (?x) + % + ( \( ({{identifier}}) \) )? # mapping key + \#? # alternate form + 0? # pad with zeros + \-? # left-adjust + \ ? # implicit sign + [+-]? # sign + (\d*|\*) # width + (\. (\d*|\*))? # precision + [hlL]? # length modifier (but ignored) + [acdeEfFgGiorsuxX%] + scope: constant.other.placeholder.python + captures: + 2: variable.other.placeholder.python + - match: '{{strftime_spec}}' + scope: constant.other.placeholder.python + - match: '\{\{|\}\}' + scope: constant.character.escape.python + - include: formatting-syntax + + formatting-syntax: + # https://docs.python.org/3.6/library/string.html#formatstrings + - match: |- # simple form + (?x) + (\{) + (?: [\w.\[\]]+)? # field_name + ( ! [ars])? # conversion + ( : (?:{{format_spec}}| # format_spec OR + [^}%]*%.[^}]*) # any format-like string + )? + (\}) + scope: constant.other.placeholder.python + captures: + 1: punctuation.definition.placeholder.begin.python + 2: storage.modifier.conversion.python + 3: constant.other.format-spec.python + 4: punctuation.definition.placeholder.end.python + - match: \{(?=[^\}"']+\{[^"']*\}) # complex (nested) form + scope: punctuation.definition.placeholder.begin.python + push: + - meta_scope: constant.other.placeholder.python + - match: \} + scope: punctuation.definition.placeholder.end.python + pop: true + - match: '[\w.\[\]]+' + - match: '![ars]' + scope: storage.modifier.conversion.python + - match: ':' + push: + - meta_scope: meta.format-spec.python constant.other.format-spec.python + - match: (?=\}) + pop: true + - include: formatting-syntax + + f-string-content: + # https://www.python.org/dev/peps/pep-0498/ + # https://docs.python.org/3.6/reference/lexical_analysis.html#f-strings + - match: \{\{|\}\} + scope: constant.character.escape.python + - match: \{\s*\} + scope: invalid.illegal.empty-expression.python + - match: (?=\{) + push: f-string-replacement + - match: \} + scope: invalid.illegal.stray-brace.python + + f-string-content-with-regex: + # Same as f-string-content, but will reset the entire scope stack + # and has an additional match. + - match: \\(\{\{|\}\}) + scope: constant.character.escape.backslash.regexp + captures: + 1: constant.character.escape.python + - match: \{\{|\}\} + scope: constant.character.escape.python + - match: \{\s*\} + scope: invalid.illegal.empty-expression.python + - match: (?=\{) + push: f-string-replacement-reset + - match: \} + scope: invalid.illegal.stray-brace.python + + f-string-replacement: + - clear_scopes: 1 + - match: \} + scope: meta.interpolation.python punctuation.section.interpolation.end.python + pop: true + - match: \{ + scope: punctuation.section.interpolation.begin.python + push: + - meta_scope: meta.interpolation.python + - match: (?=\}) + pop: true + - match: '![ars]' + scope: storage.modifier.conversion.python + - match: = + scope: storage.modifier.debug.python + - match: ':' + push: + - meta_scope: meta.format-spec.python constant.other.format-spec.python + # Because replacements can also be used *within* the format-spec, + # basically any character is valid and matching {{format_spec}} is useless. + # - match: '{{format_spec}}' + - match: (?=\}) + pop: true + - include: f-string-content + - match: '' + push: + - meta_content_scope: source.python.embedded + - match: (?==?(![^=]|:|\})) + pop: true + - match: \\ + scope: invalid.illegal.backslash-in-fstring.python + - include: inline-for + - include: expressions + + f-string-replacement-reset: + # Same as f-string-replacement, but with clear_scopes: true + - clear_scopes: true + - meta_scope: source.python meta.string.interpolated.python + - match: \} + scope: meta.interpolation.python punctuation.section.interpolation.end.python + pop: true + - match: \{ + scope: punctuation.section.interpolation.begin.python + push: + - meta_scope: meta.interpolation.python + - match: (?=\}) + pop: true + - match: '![ars]' + scope: storage.modifier.conversion.python + - match: ':' + push: + - meta_scope: meta.format-spec.python constant.other.format-spec.python + - match: (?=\}) + pop: true + - include: f-string-content + - match: '' + push: + - meta_content_scope: source.python.embedded + - match: (?=![^=]|:|\}) + pop: true + - match: \\ + scope: invalid.illegal.backslash-in-fstring.python + - include: inline-for + - include: expressions + + string-quoted-double-block: + # Triple-quoted capital R raw string, unicode or not, no syntax embedding + - match: '([uU]?R)(""")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-unicode-char + # Triple-quoted capital R raw string, bytes, no syntax embedding + - match: '([bB]R|R[bB])(""")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + # Triple-quoted raw string, unicode or not, will detect SQL, otherwise regex + - match: '([uU]?r)(""")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.block.python + - match: '(?={{sql_indicator}})' + set: + - meta_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + push: scope:source.sql + with_prototype: + - match: '(?=""")' + pop: true + - include: escaped-unicode-char + - include: constant-placeholder + - match: '(?=\S)' + set: + - meta_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: '(?=""")' + pop: true + - include: escaped-unicode-char + # Triple-quoted raw string, bytes, will use regex + - match: '([bB]r|r[bB])(""")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + embed: scope:source.regexp.python + escape: (?=""") + # Triple-quoted raw f-string + - match: ([fF]R|R[fF])(""") + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.begin.python + set: after-expression + - include: f-string-content + # Triple-quoted raw f-string, treated as regex + - match: ([fF]r|r[fF])(""") + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.begin.python + set: after-expression + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: '(?=""")' + pop: true + - include: line-continuation-inside-string + - include: f-string-content-with-regex + # Triple-quoted f-string + - match: ([fF])(""") + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.begin.python + set: after-expression + - include: escaped-fstring-escape + - include: escaped-unicode-char + - include: escaped-char + - include: f-string-content + # Triple-quoted string, unicode or not, will detect SQL + - match: '([uU]?)(""")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.block.python + - match: '(?={{sql_indicator}})' + set: + - meta_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + push: scope:source.sql + with_prototype: + - match: '(?=""")' + pop: true + - include: escaped-unicode-char + - include: escaped-char + - include: constant-placeholder + - match: '(?=\S)' + set: + - meta_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-unicode-char + - include: escaped-char + - include: constant-placeholder + # Triple-quoted string, bytes, no syntax embedding + - match: '([bB])(""")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.block.python + - match: '"""' + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-char + - include: constant-placeholder + + string-quoted-double: + # Single-line capital R raw string, unicode or not, no syntax embedding + - match: '([uU]?R)(")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + # Single-line capital R raw string, bytes, no syntax embedding + - match: '([bB]R|R[bB])(")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + # Single-line raw string, unicode or not, starting with a SQL keyword + - match: '([uU]?r)(")(?={{sql_indicator}})' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.sql + with_prototype: + - match: '(?="|\n)' + pop: true + - include: constant-placeholder + - include: line-continuation-inside-string + # Single-line raw string, unicode or not, treated as regex + - match: '([uU]?r)(")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: '(?="|\n)' + pop: true + - include: line-continuation-inside-string + # Single-line raw string, bytes, treated as regex + - match: '([bB]r|r[bB])(")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + embed: scope:source.regexp.python + escape: (?="|\n) + # Single-line raw f-string + - match: (R[fF]|[fF]R)(") + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - include: f-string-content + # Single-line raw f-string, treated as regex + - match: (r[fF]|[fF]r)(") + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: '(?="|\n)' + pop: true + - include: line-continuation-inside-string + - include: f-string-content-with-regex + # Single-line f-string + - match: ([fF])(") + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-fstring-escape + - include: escaped-unicode-char + - include: escaped-char + - include: line-continuation-inside-string + - include: f-string-content + # Single-line string, unicode or not, starting with a SQL keyword + - match: '([uU]?)(")(?={{sql_indicator}})' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.sql + with_prototype: + - match: '(?="|\n)' + pop: true + - include: escaped-unicode-char + - include: escaped-char + - include: line-continuation-inside-string + - include: constant-placeholder + # Single-line string, unicode or not + - match: '([uU]?)(")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-unicode-char + - include: escaped-char + - include: line-continuation-inside-string + - include: constant-placeholder + # Single-line string, bytes + - match: '([bB])(")' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.double.python + - match: '"' + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-char + - include: line-continuation-inside-string + - include: constant-placeholder + + string-quoted-single-block: + # Triple-quoted capital R raw string, unicode or not, no syntax embedding + - match: ([uU]?R)(''') + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + # Triple-quoted capital R raw string, bytes, no syntax embedding + - match: ([bB]R|R[bB])(''') + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + # Triple-quoted raw string, unicode or not, will detect SQL, otherwise regex + - match: ([uU]?r)(''') + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.block.python + - match: '(?={{sql_indicator}})' + set: + - meta_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + push: scope:source.sql + with_prototype: + - match: (?=''') + pop: true + - include: escaped-unicode-char + - include: escaped-char + - include: constant-placeholder + - match: '(?=\S)' + set: + - meta_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: (?=''') + pop: true + - include: escaped-unicode-char + # Triple-quoted raw string, bytes, will use regex + - match: ([bB]r|r[bB])(''') + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + embed: scope:source.regexp.python + escape: (?=''') + # Triple-quoted raw f-string + - match: ([fF]R|R[fF])(''') + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.begin.python + set: after-expression + - include: f-string-content + # Triple-quoted raw f-string, treated as regex + - match: ([fF]r|r[fF])(''') + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.begin.python + set: after-expression + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: (?=''') + pop: true + - include: line-continuation-inside-string + - include: f-string-content-with-regex + # Triple-quoted f-string + - match: ([fF])(''') + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.begin.python + set: after-expression + - include: escaped-fstring-escape + - include: escaped-unicode-char + - include: escaped-char + - include: f-string-content + # Triple-quoted string, unicode or not, will detect SQL + - match: ([uU]?)(''') + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.block.python + - match: '(?={{sql_indicator}})' + set: + - meta_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + - match: '' + push: scope:source.sql + with_prototype: + - match: (?=''') + pop: true + - include: escaped-unicode-char + - include: escaped-char + - include: constant-placeholder + - match: '(?=\S)' + set: + - meta_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-unicode-char + - include: escaped-char + - include: constant-placeholder + # Triple-quoted string, bytes, no syntax embedding + - match: ([bB])(''') + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.block.python + - match: "'''" + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-char + - include: constant-placeholder + + string-quoted-single: + # Single-line capital R raw string, unicode or not, no syntax embedding + - match: '([uU]?R)('')' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + # Single-line capital R raw string, bytes, no syntax embedding + - match: '([bB]R|R[bB])('')' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + # Single-line raw string, unicode or not, starting with a SQL keyword + - match: '([uU]?r)('')(?={{sql_indicator}})' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.sql + with_prototype: + - match: '(?=''|\n)' + pop: true + - include: line-continuation-inside-string + - include: constant-placeholder + # Single-line raw string, unicode or not, treated as regex + - match: '([uU]?r)('')' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: '(?=''|\n)' + pop: true + - include: line-continuation-inside-string + # Single-line raw string, bytes, treated as regex + - match: '([bB]r|r[bB])('')' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: '(?=''|\n)' + pop: true + - include: line-continuation-inside-string + # Single-line raw f-string + - match: ([fF]R|R[fF])(') + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - include: f-string-content + # Single-line raw f-string, treated as regex + - match: ([fF]r|r[fF])(') + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.regexp.python + with_prototype: + - match: (?='|\n) + pop: true + - include: line-continuation-inside-string + - include: f-string-content-with-regex + # Single-line f-string + - match: ([fF])(') + captures: + 1: storage.type.string.python + 2: meta.string.interpolated.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.interpolated.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-fstring-escape + - include: escaped-unicode-char + - include: escaped-char + - include: line-continuation-inside-string + - include: f-string-content + # Single-line string, unicode or not, starting with a SQL keyword + - match: '([uU]?)('')(?={{sql_indicator}})' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: line-continuation-inside-string + - match: '' + push: scope:source.sql + with_prototype: + - match: '(?=''|\n)' + pop: true + - include: escaped-unicode-char + - include: escaped-char + - include: line-continuation-inside-string + - include: constant-placeholder + # Single-line string, unicode or not + - match: '([uU]?)('')' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-unicode-char + - include: escaped-char + - include: line-continuation-inside-string + - include: constant-placeholder + # Single-line string, bytes + - match: '([bB])('')' + captures: + 1: storage.type.string.python + 2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python + push: + - meta_content_scope: meta.string.python string.quoted.single.python + - match: "'" + scope: punctuation.definition.string.end.python + set: after-expression + - include: escaped-char + - include: line-continuation-inside-string + - include: constant-placeholder + + strings: + # block versions must be matched first + - include: string-quoted-double-block + - include: string-quoted-double + - include: string-quoted-single-block + - include: string-quoted-single + + inline-for: + - match: \b(?:(async)\s+)?(for)\b + captures: + 1: storage.modifier.async.python + 2: keyword.control.loop.for.generator.python + push: + - include: comments + - meta_scope: meta.expression.generator.python + - match: \bin\b + scope: keyword.control.loop.for.in.python + pop: true + - match: '(?=[)\]}])' + scope: invalid.illegal.missing-in.python + pop: true + - include: illegal-names-pop + - include: target-list + + inline-if: + - match: \bif\b + scope: keyword.control.conditional.if.python + - match: \belse\b + scope: keyword.control.conditional.else.python + + target-list: + - match: ',' + scope: punctuation.separator.target-list.python + - match: \( + scope: punctuation.section.target-list.begin.python + push: + - include: comments + - match: ',' + scope: punctuation.separator.target-list.python + - match: \) + scope: punctuation.section.target-list.end.python + pop: true + - include: target-list + - include: name + - include: name