--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/ftdetect/snakemake.vim Tue Aug 29 15:05:19 2023 -0400
@@ -0,0 +1,9 @@
+" Vim ftdetect file
+" Language: Snakemake (extended from python.vim)
+" Maintainer: Jay Hesselberth (jay.hesselberth@gmail.com)
+" Last Change: 2020 Oct 6
+"
+" Usage
+"
+" copy to $HOME/.vim/ftdetect directory
+au BufNewFile,BufRead Snakefile,*.smk set filetype=snakemake
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/ftplugin/snakemake/folding.vim Tue Aug 29 15:05:19 2023 -0400
@@ -0,0 +1,61 @@
+setlocal foldmethod=expr
+setlocal foldexpr=GetSnakemakeFold(v:lnum)
+
+function! GetSnakemakeFold(lnum)
+ " fold preamble
+ if a:lnum == 1
+ return '>1'
+ endif
+
+ let thisline = getline(a:lnum)
+
+ " blank lines end folds
+ if thisline =~? '\v^\s*$'
+ return '-1'
+ " start fold on top level rules or python objects
+ elseif thisline =~? '\v^(rule|def|checkpoint|class)'
+ return ">1"
+ elseif thisline =~? '\v^\S'
+ if PreviousLineIndented(a:lnum) && NextRuleIndented(a:lnum)
+ return ">1"
+ endif
+ endif
+
+ return "="
+
+endfunction
+
+function! NextRuleIndented(lnum)
+ let numlines = line('$')
+ let current = a:lnum + 1
+
+ while current <= numlines
+ let thisline = getline(current)
+ if thisline =~? '\v^(rule|def|checkpoint|class)'
+ return 0
+ elseif thisline =~? '\v^\s+(rule|checkpoint)'
+ return 1
+ endif
+
+ let current += 1
+ endwhile
+
+ return 0
+endfunction
+
+function! PreviousLineIndented(lnum)
+ let current = a:lnum - 1
+
+ while current >= 1
+ let thisline = getline(current)
+ if thisline =~? '\v^\S'
+ return 0
+ elseif thisline =~? '\v^\s+\S'
+ return 1
+ endif
+
+ let current -= 1
+ endwhile
+
+ return 0
+endfunction
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/ftplugin/snakemake/sections.vim Tue Aug 29 15:05:19 2023 -0400
@@ -0,0 +1,43 @@
+function! s:NextSection(type, backwards, visual)
+ if a:visual
+ normal! gv
+ endif
+
+ if a:type == 1
+ let pattern = '\v(^rule|^checkpoint|^def|%^)'
+ elseif a:type == 2
+ let pattern = '\v\n\zs\n^(rule|checkpoint|def)'
+ endif
+
+ if a:backwards
+ let dir = '?'
+ else
+ let dir = '/'
+ endif
+
+ execute 'silent normal! ' . dir . pattern . dir . "\r"
+endfunction
+
+noremap <script> <buffer> <silent> ]]
+ \ :call <SID>NextSection(1, 0, 0)<cr>
+
+noremap <script> <buffer> <silent> [[
+ \ :call <SID>NextSection(1, 1, 0)<cr>
+
+noremap <script> <buffer> <silent> ][
+ \ :call <SID>NextSection(2, 0, 0)<cr>
+
+noremap <script> <buffer> <silent> []
+ \ :call <SID>NextSection(2, 1, 0)<cr>
+
+vnoremap <script> <buffer> <silent> ]]
+ \ :<c-u>call <SID>NextSection(1, 0, 1)<cr>
+
+vnoremap <script> <buffer> <silent> [[
+ \ :<c-u>call <SID>NextSection(1, 1, 1)<cr>
+
+vnoremap <script> <buffer> <silent> ][
+ \ :<c-u>call <SID>NextSection(2, 0, 1)<cr>
+
+vnoremap <script> <buffer> <silent> []
+ \ :<c-u>call <SID>NextSection(2, 1, 1)<cr>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/syntax/snakemake.vim Tue Aug 29 15:05:19 2023 -0400
@@ -0,0 +1,126 @@
+" Vim syntax file
+" Language: Snakemake (extended from python.vim)
+" Maintainer: Jay Hesselberth (jay.hesselberth@gmail.com)
+" Last Change: 2020 Oct 6
+"
+" Usage
+"
+" copy to $HOME/.vim/syntax directory and
+" copy to ftdetect/snakemake.vim to $HOME/.vim/ftdetect directory
+"
+" force coloring in a vim session with:
+"
+" :set syntax=snakemake
+"
+if exists("b:current_syntax")
+ finish
+endif
+
+" load settings from system python.vim (7.4)
+source $VIMRUNTIME/syntax/python.vim
+source $VIMRUNTIME/indent/python.vim
+
+"
+" Snakemake rules, as of version 5.8
+"
+"
+" rule = "rule" (identifier | "") ":" ruleparams
+" include = "include:" stringliteral
+" workdir = "workdir:" stringliteral
+" ni = NEWLINE INDENT
+" ruleparams = [ni input] [ni output] [ni params] [ni message] [ni threads] [ni (run | shell)] NEWLINE snakemake
+" input = "input" ":" parameter_list
+" output = "output" ":" parameter_list
+" params = "params" ":" parameter_list
+" message = "message" ":" stringliteral
+" threads = "threads" ":" integer
+" resources = "resources" ":" parameter_list
+" version = "version" ":" statement
+" run = "run" ":" ni statement
+" shell = "shell" ":" stringliteral
+" singularity = "singularity" ":" stringliteral
+" conda = "conda" ":" stringliteral
+" shadow = "shadow" ":" stringliteral
+" group = "group" ":" stringliteral
+
+
+" general directives (e.g. input)
+syn keyword pythonStatement
+ \ benchmark
+ \ conda
+ \ configfile
+ \ container
+ \ default_target
+ \ envmodules
+ \ group
+ \ include
+ \ input
+ \ localrule
+ \ localrules
+ \ log
+ \ message
+ \ notebook
+ \ onerror
+ \ onstart
+ \ onsuccess
+ \ output
+ \ params
+ \ priority
+ \ resources
+ \ ruleorder
+ \ run
+ \ scattergather
+ \ script
+ \ shadow
+ \ shell
+ \ singularity
+ \ snakefile
+ \ template_engine
+ \ threads
+ \ version
+ \ wildcard_constraints
+ \ wildcards
+ \ workdir
+ \ wrapper
+
+" directives with a label (e.g. rule)
+syn keyword pythonStatement
+ \ checkpoint
+ \ rule
+ \ subworkflow
+ \ nextgroup=pythonFunction skipwhite
+
+" common snakemake objects
+syn keyword pythonBuiltinObj
+ \ Paramspace
+ \ checkpoints
+ \ config
+ \ gather
+ \ rules
+ \ scatter
+ \ workflow
+
+" snakemake functions
+syn keyword pythonBuiltinFunc
+ \ ancient
+ \ directory
+ \ expand
+ \ multiext
+ \ pipe
+ \ protected
+ \ read_job_properties
+ \ service
+ \ temp
+ \ touch
+ \ unpack
+
+" similar to special def and class treatment from python.vim, except
+" parenthetical part of def and class
+syn match pythonFunction
+ \ "\%(\%(rule\s\|subworkflow\s\|checkpoint\s\)\s*\)\@<=\h\w*" contained
+
+syn sync match pythonSync grouphere NONE "^\s*\%(rule\|subworkflow\|checkpoint\)\s\+\h\w*\s*"
+
+let b:current_syntax = "snakemake"
+
+" vim:set sw=2 sts=2 ts=8 noet: