From c4ef3349a056401a82e094922124bc4013d4c804 Mon Sep 17 00:00:00 2001 From: Rob Flickenger Date: Mon, 29 Sep 2014 15:34:52 -0700 Subject: [PATCH] Initial version, v0.0.1 --- Default (Linux).sublime-keymap | 6 +++ Default (OSX).sublime-keymap | 6 +++ Default (Windows).sublime-keymap | 6 +++ Main.sublime-menu | 16 ++++++++ README.md | 23 ++++++++++++ actg.JSON-tmLanguage | 40 ++++++++++++++++++++ actg.py | 57 ++++++++++++++++++++++++++++ actg.tmLanguage | 64 ++++++++++++++++++++++++++++++++ 8 files changed, 218 insertions(+) create mode 100644 Default (Linux).sublime-keymap create mode 100644 Default (OSX).sublime-keymap create mode 100644 Default (Windows).sublime-keymap create mode 100644 Main.sublime-menu create mode 100644 README.md create mode 100644 actg.JSON-tmLanguage create mode 100644 actg.py create mode 100644 actg.tmLanguage diff --git a/Default (Linux).sublime-keymap b/Default (Linux).sublime-keymap new file mode 100644 index 0000000..6a9761e --- /dev/null +++ b/Default (Linux).sublime-keymap @@ -0,0 +1,6 @@ +[ + { + "keys": ["ctrl+shift+r"], + "command": "reverse_complement" + } +] \ No newline at end of file diff --git a/Default (OSX).sublime-keymap b/Default (OSX).sublime-keymap new file mode 100644 index 0000000..056651e --- /dev/null +++ b/Default (OSX).sublime-keymap @@ -0,0 +1,6 @@ +[ + { + "keys": ["super+shift+r"], + "command": "reverse_complement" + } +] \ No newline at end of file diff --git a/Default (Windows).sublime-keymap b/Default (Windows).sublime-keymap new file mode 100644 index 0000000..6a9761e --- /dev/null +++ b/Default (Windows).sublime-keymap @@ -0,0 +1,6 @@ +[ + { + "keys": ["ctrl+shift+r"], + "command": "reverse_complement" + } +] \ No newline at end of file diff --git a/Main.sublime-menu b/Main.sublime-menu new file mode 100644 index 0000000..d932ef2 --- /dev/null +++ b/Main.sublime-menu @@ -0,0 +1,16 @@ +[ + { + "id": "edit", + "children": [ + { + "caption": "Nucleotides", + "id": "nucleotides", + "children": [ + { + "command": "reverse_complement" + } + ] + } + ] + } +] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..69ca346 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +ACTG for SublimeText +==================== + +Nucleotide syntax highlighting and reverse complement support. This is handy for "stare at the screen and squint" DNA analysis. + +Features +-------- + +* Choose 'Nucleotides' syntax highlighting to colorize ACTG and N. +* Automatically associates .fa, .fasta, .fq, .fastq, .sam, and .vcf files. +* Make a selection and hit Control-Shift-R (or Command-Shift-R on Mac) to replace it with the reverse complement. + +Bugs +---- + +* ACTG and N are simply highlighted in place, which can make for some interestingly colored VCF comments and quality strings. A more clever regex would help, if only I could fathom the tmLanguage backreference match syntax. + +Patches welcome. + +Releases +-------- + +* 0.0.1: Initial release, 2014-09-29 diff --git a/actg.JSON-tmLanguage b/actg.JSON-tmLanguage new file mode 100644 index 0000000..52e8cf9 --- /dev/null +++ b/actg.JSON-tmLanguage @@ -0,0 +1,40 @@ +{ + "name": "Nucleotides", + "scopeName": "source.nucleotides", + "fileTypes": [ + "fq", + "fastq", + "fa", + "fasta", + "sam", + "vcf" + ], + "patterns": [ + { + "match": "A", + "name": "keyword.control.nucleotides", + "comment": "adenine" + }, + { + "match": "C", + "name": "entity.name.function.nucleotides", + "comment": "cytosine" + }, + { + "match": "T", + "name": "constant.numeric.source.nucleotides", + "comment": "thymine" + }, + { + "match": "G", + "name": "string.quoted.source.nucleotides", + "comment": "guanine" + }, + { + "match": "N", + "name": "comment.block.source.nucleotides", + "comment": "unknown" + } + ], + "uuid": "34f308ec-03a9-428e-93dd-d8eae6648d7f" +} \ No newline at end of file diff --git a/actg.py b/actg.py new file mode 100644 index 0000000..b7f56c8 --- /dev/null +++ b/actg.py @@ -0,0 +1,57 @@ +''' + actg.py + + Reverse complement plugin for Sublime Text 2 +''' +import sublime, sublime_plugin + +class ReverseComplementCommand(sublime_plugin.TextCommand): + def complement(self, sequence, reverse=False): + """ + Compute the complement of a DNA sequence. + + If reverse is True, reverse it too. + """ + flip = { + 'A': 'T', + 'C': 'G', + 'G': 'C', + 'T': 'A', + 'N': 'N', + 'a': 't', + 'c': 'g', + 'g': 'c', + 't': 'a', + 'n': 'n' + } + + complines = [] + + # Gracefully handle line endings + if '\n' in sequence: + postfix = '\n' + else: + postfix = '' + + for line in sequence.split('\n'): + line_complement = [] + for i in list(line): + if not i in flip: + sublime.error_message('Selection contains non-nucleotides.') + return False + line_complement.append(flip[i]) + + if reverse: + complines.append(''.join(line_complement[::-1])) + else: + complines.append(''.join(line_complement)) + + return postfix.join(complines) + + def run(self, edit): + sels = self.view.sel() + for sel in sels: + if not sel.empty(): + ret = self.complement(self.view.substr(sel), reverse=True) + if(ret): + self.view.replace(edit, sel, ret) diff --git a/actg.tmLanguage b/actg.tmLanguage new file mode 100644 index 0000000..2115a99 --- /dev/null +++ b/actg.tmLanguage @@ -0,0 +1,64 @@ + + + + + fileTypes + + fq + fastq + fa + fasta + sam + vcf + + name + Nucleotides + patterns + + + comment + adenine + match + A + name + keyword.control.nucleotides + + + comment + cytosine + match + C + name + entity.name.function.nucleotides + + + comment + thymine + match + T + name + constant.numeric.source.nucleotides + + + comment + guanine + match + G + name + string.quoted.source.nucleotides + + + comment + unknown + match + N + name + comment.block.source.nucleotides + + + scopeName + source.nucleotides + uuid + 34f308ec-03a9-428e-93dd-d8eae6648d7f + +