Skip to content

fix: make snakemake variable colorful in functions ... #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
{
"version": "0.2.0",
"version": "0.2.0",
"configurations": [
{
"name": "Extension",
Expand Down
113 changes: 69 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,59 +26,84 @@ Example taken from [Snakemake documentation](https://snakemake.readthedocs.io/en

<details>

<summary>Keywords and Functions</summary>
<summary>[Keywords and Functions](src/keywords.yaml)</summary>

- Configurations
- configfile
- include
- localrules
- onerror
- onstart
- onsuccess
- ruleorder
- snakefile
- workdir
- Rules
- checkpoint
- rule
- subworkflow
- these keywords specified in the format `<keyword>: <values>` within a snakefile.
- for example:
```snakemake
configfile: "config.yaml"

onsuccess:
print("All jobs finished successfully.")

include: "workflow/report.smk"
```

- [Rules and Modules](https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#snakefiles-and-rules)
- `rule <rulename>:` defines a rule with its parameters, followed by an indented body
- [`checkpoint <rulename>:`] is a special type of `rule` that allows dynamic determination of workflow steps based on its output.
- `module <modulename>:` declares a module repository from which rules can be imported
- `subworkflow` is now deprecated

- Rule Parameters
- benchmark
- conda
- cwl
- group
- input
- log
- message
- output
- params
- priority
- resources
- run
- script
- shadow
- shell
- singularity
- threads
- version
- wildcard_constraints
- wrapper
- Functions
- ancient
- directory
- expand
- pipe
- protected
- temp
- touch
- unpack
- Used in `rule` and `checkpoint` blocks to define inputs, outputs, and other settings.
- You can re- `used rule <rulename> as <newrulename> ... with` different parameters, but you cannot change the way it runs, including:
- run
- shell
- script
- [`notebook`](https://snakemake.readthedocs.io/en/stable/tutorial/interaction_visualization_reporting/tutorial.html#tutorial-interaction-visualization-and-reporting-with-snakemake)
- [`wrapper`](https://snakemake.readthedocs.io/en/stable/snakefiles/modularization.html#wrappers)
- template_engine
- [`cwl`](https://snakemake.readthedocs.io/en/stable/snakefiles/modularization.html#common-workflow-language-cwl-support)

- [Module Parameters](https://snakemake.readthedocs.io/en/stable/snakefiles/modularization.html#modules):
- Define where and how to import rules when using the `module` directive.
- Example:
```snakemake
module remote:
snakefile: "local.smk"
config: {**config, "remote": True}
replace_prefix: "local/"
prefix: "remote/"

use rule * from remote as remote_*
```

- Global Variables:
- The following classes are available without explicit import from the snakemake module:
- `Path`
- `WorkflowError`
- Important variables used across workflows include:
- snakemake
- `rules`: reference rules via `rules.<rulename>`
- workflow
- `checkpoints`: access outputs of [checkpoint](https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#data-dependent-conditional-execution) rules
- [`storage`](https://snakemake.readthedocs.io/en/stable/snakefiles/storage.html#storage-support)
- [`access`](https://snakemake.readthedocs.io/en/stable/snakefiles/storage.html#access-pattern-annotation)
- [`scatter` and `gather`](https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#defining-scatter-gather-processes)

- Job Parameters:
- These parameters are only available during job execution and should be used within `run` or `shell` blocks
- input
- output
- params
- wildcards
- threads
- resources
- log
- [`config`](https://snakemake.readthedocs.io/en/stable/snakefiles/configuration.html#configuration) is a dict that contains the configuration values and can be accessed everywhere

- Functions:
- Various [built-in helper functions](https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#helpers-for-defining-rules) are available for use without needing to import them

</details>

## TODO

- [ ] recognize files provided as string after `include:`, `conda`, `snakefile`, and allow quickly jumping to them
- [ ] add bash-color to docstring in `shell:` block
- [ ] Indentation rules (really tricky for some reason)
- [ ] Recognize string substitutions: `"command {input}"`
- [ ] Recognize wildcard constraints inside string substitutions: `"{sample,[A-Za-z0-9]+}"`

## Snakemake Support for other Editors
Expand Down
171 changes: 119 additions & 52 deletions src/yaml/snakemake.syntax.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ scopeName: source.python.snakemake
fileTypes: [Snakefile, smk]

patterns:
- include: "#quotessmall"
- include: "#quotesmid"
- include: "#quotesbig"
# - include: "#shellzone"
- include: "#snakestrings"
- include: "#configs"
- include: "#rules"
- include: "#modules"
Expand All @@ -16,54 +15,88 @@ patterns:
- include: "#ruleparams"
- include: "#rulerunparams"
- include: "#moduleparams"
- include: "#classes"
- include: "#object"
- include: "#ruleargargs"
- include: "#ruleargs"
- include: "#functions"
# - include: '#snakestrings'
- include: "#function-call"
- include: "#quoteall"
- include: "#snakemakenames"
- include: source.python

repository:
quotessmall:
begin: \(
end: \)
function-call:
name: meta.function-call.snakemake
comment: Regular function call of the type "name(args)" in snakemake
begin: |
(?x)
\b(?=
([[:alpha:]_]\w*) \s* (\()
)
end: (\))
endCaptures:
"1": { name: punctuation.definition.arguments.end.python }
patterns:
- include: "#classes"
- include: "#functions"
- include: "source.python#special-variables"
- include: "source.python#function-name"
- include: "#function-arguments"
function-arguments:
begin: (\()
end: (?=\))(?!\)\s*\()
beginCaptures:
"1": { name: punctuation.definition.arguments.begin.python }
contentName: meta.function-call.arguments.python
patterns:
- name: punctuation.separator.arguments.python
match: (,)
- match: |
(?x)
(?:(?<=[,(])|^) \s* (\*{1,2})
captures:
"1": { name: keyword.operator.unpacking.arguments.python }
- include: "#snakemakenames"
- include: "source.python#lambda-incomplete"
- include: "source.python#illegal-names"
- match: '\b([[:alpha:]_]\w*)\s*(=)(?!=)'
captures:
"1": { name: variable.parameter.function-call.python }
"2": { name: keyword.operator.assignment.python }

- name: keyword.operator.assignment.python
match: =(?!=)
- include: "#snakemakenames"
- include: "#quoteall"
- include: "source.python#expression"
- match: \s*(\))\s*(\()
captures:
"1": { name: punctuation.definition.arguments.end.python }
"2": { name: punctuation.definition.arguments.begin.python }

quoteall:
patterns:
- include: "#quotessmall"
- include: "#quotesmid"
- include: "#quotesbig"
- include: "#classes"
- include: "#object"
- include: "#ruleargargs"
- include: "#ruleargs"
- include: "#functions"
- include: source.python
quotessmall:
begin: \(
end: \)
patterns:
- include: "#quoteall"
- include: "#snakemakenames"
- include: "source.python"
quotesmid:
begin: \[
end: \]
patterns:
- include: "#quotessmall"
- include: "#quotesmid"
- include: "#quotesbig"
- include: "#classes"
- include: "#object"
- include: "#ruleargargs"
- include: "#ruleargs"
- include: "#functions"
- include: source.python
- include: "#quoteall"
- include: "#snakemakenames"
- include: "source.python"
quotesbig:
begin: \{
end: \}
patterns:
- include: "#quotessmall"
- include: "#quotesmid"
- include: "#quotesbig"
- include: "#classes"
- include: "#object"
- include: "#ruleargargs"
- include: "#ruleargs"
- include: "#functions"
- include: source.python
- include: "#quoteall"
- include: "#snakemakenames"
- include: "source.python"

configs:
match: >
(?x)
Expand Down Expand Up @@ -106,23 +139,20 @@ repository:
"3": { name: keyword.control.snakemake }
"4": { name: entity.name.function.snakemake.rule }
"5": { name: keyword.control.snakemake }

userulesfromas:
match: >
(?x)
\b(use\s+rule)\s+(\w+|\w+\*|\*)\s+(from)\s+(\w+)\s+(as)\s+(\w+|\w+\*)
# may end with a "with:"", but that can be caught by other rules
captures:
"1": { name: keyword.control.snakemake }
"2": { name: entity.name.function.snakemake.rule }
"3": { name: keyword.control.snakemake }
"4": { name: entity.name.type.snakemake.rule }
"5": { name: keyword.control.snakemake }
"6": { name: entity.name.function.snakemake.rule }

userulesfrom:
match: >
(?x)
\b(use\s+rule)\s+(\w+|\w+\*|\*)\s+(from)\s+(\w+)
match: \b(use\s+rule)\s+(\w+|\w+\*|\*)\s+(from)\s+(\w+)
captures:
"1": { name: keyword.control.snakemake }
"2": { name: entity.name.function.snakemake.rule }
Expand All @@ -137,7 +167,6 @@ repository:
: # Ending in colon
captures:
"1": { name: keyword.control.snakemake.ruleparam }

rulerunparams:
match: >
(?x)
Expand All @@ -155,34 +184,72 @@ repository:
captures:
"1": { name: keyword.control.snakemake.moduleparam }

snakemakenames:
patterns:
- include: "#classes"
- include: "#rulesrefernce"
- include: "#objects"
- include: "#ruleargargs"
- include: "#ruleargs"
- include: "#functions"
classes:
match: \b({{classes}})\b(?!\s*=)
captures:
"1": { name: entity.name.type.class.snakemake }

rulesrefernce:
name: meta.class.snakemake
match: \b(rules|checkpoints)\s*\.\s*([A-Za-z_]+)\b(?!\s*=)
captures:
"1": { name: entity.name.type.class.snakemake }
"2": { name: entity.name.variable.snakemake }
objects:
name: meta.c
match: \b({{objects}})\b(?!\s*=)
captures:
"1": { name: entity.name.type.class.snakemake }

ruleargargs:
name: meta.args.snakemake
match: \b({{ruleargs}})\s*\.\s*([A-Za-z_]+)\b(?!\s*=)
captures:
"1": { name: entity.name.variable.snakemake }
"1": { name: constant.language.snakemake }
"2": { name: entity.name.variable.snakemake }

ruleargs:
match: \b({{ruleargs}})\b(?!\s*=)
captures:
"1": { name: entity.name.variable.snakemake }

"1": { name: constant.language.snakemake }
functions:
match: \b({{functions}})\b(?!\s*=)
captures:
"1": { name: support.function.builtin.snakemake }

shell_block:
begin: ^\s+shell:\s*\n*\s*\"\"\"
end: \"\"\"
snakestrings:
name: string.quoted.docstring.snakemake
begin: \s+(\'\'\'|\"\"\"|\'|\")
end: (\1)
beginCaptures:
"1": { name: punctuation.definition.string.begin.python }
endCaptures:
"1": { name: punctuation.definition.string.end.python }
patterns:
- include: "source.python#string-single-bad-brace1-formatting-unicode"
- include: "source.python#string-single-bad-brace2-formatting-unicode"
- include: "source.python#string-unicode-guts"

shellzone:
name: meta.embedded.shell.snakemake
begin: '^(\s+)\s(shell)\s*:'
beginCaptures:
"2": { name: entity.name.type.class.snakemake }
while: ^(?:(\1.*)|)$
patterns:
- include: "#snakeshellstrings"
snakeshellstrings:
name: string.quoted.docstring.snakemake.shell
begin: \s+(\'\'\'|\"\"\")
end: (\1)
beginCaptures:
"1": { name: punctuation.definition.string.begin.python }
endCaptures:
"1": { name: punctuation.definition.string.end.python }
patterns:
- include: source.shell
- include: "source.shell"
Loading