diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7f3ba45
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.pyc
+*.cache
diff --git a/ASP/ASP.tmLanguage.cache b/ASP/ASP.tmLanguage.cache
deleted file mode 100644
index c0d2381..0000000
Binary files a/ASP/ASP.tmLanguage.cache and /dev/null differ
diff --git a/ASP/HTML-ASP.tmLanguage.cache b/ASP/HTML-ASP.tmLanguage.cache
deleted file mode 100644
index 9804707..0000000
Binary files a/ASP/HTML-ASP.tmLanguage.cache and /dev/null differ
diff --git a/ActionScript/ActionScript.tmLanguage.cache b/ActionScript/ActionScript.tmLanguage.cache
deleted file mode 100644
index e3f4fa6..0000000
Binary files a/ActionScript/ActionScript.tmLanguage.cache and /dev/null differ
diff --git a/Alignment/Alignment.pyc b/Alignment/Alignment.pyc
deleted file mode 100644
index 44d6536..0000000
Binary files a/Alignment/Alignment.pyc and /dev/null differ
diff --git a/AppleScript/AppleScript.tmLanguage.cache b/AppleScript/AppleScript.tmLanguage.cache
deleted file mode 100644
index 9a1137c..0000000
Binary files a/AppleScript/AppleScript.tmLanguage.cache and /dev/null differ
diff --git a/Batch File/Batch File.tmLanguage.cache b/Batch File/Batch File.tmLanguage.cache
deleted file mode 100644
index 8253453..0000000
Binary files a/Batch File/Batch File.tmLanguage.cache and /dev/null differ
diff --git a/C#/Build.tmLanguage.cache b/C#/Build.tmLanguage.cache
deleted file mode 100644
index 7ce69df..0000000
Binary files a/C#/Build.tmLanguage.cache and /dev/null differ
diff --git a/C#/C#.tmLanguage.cache b/C#/C#.tmLanguage.cache
deleted file mode 100644
index 17ef45d..0000000
Binary files a/C#/C#.tmLanguage.cache and /dev/null differ
diff --git a/C++/C++.tmLanguage.cache b/C++/C++.tmLanguage.cache
deleted file mode 100644
index 29d6b93..0000000
Binary files a/C++/C++.tmLanguage.cache and /dev/null differ
diff --git a/C++/C.tmLanguage.cache b/C++/C.tmLanguage.cache
deleted file mode 100644
index d03c9c6..0000000
Binary files a/C++/C.tmLanguage.cache and /dev/null differ
diff --git a/C++/Comments (C++).tmPreferences.cache b/C++/Comments (C++).tmPreferences.cache
deleted file mode 100644
index 57cff8b..0000000
Binary files a/C++/Comments (C++).tmPreferences.cache and /dev/null differ
diff --git a/C++/Indentation Rules.tmPreferences.cache b/C++/Indentation Rules.tmPreferences.cache
deleted file mode 100644
index 7611b43..0000000
Binary files a/C++/Indentation Rules.tmPreferences.cache and /dev/null differ
diff --git a/C++/Symbol List - Indent Class Methods.tmPreferences.cache b/C++/Symbol List - Indent Class Methods.tmPreferences.cache
deleted file mode 100644
index f7eff23..0000000
Binary files a/C++/Symbol List - Indent Class Methods.tmPreferences.cache and /dev/null differ
diff --git a/C++/Symbol List - Prefix Banner Items.tmPreferences.cache b/C++/Symbol List - Prefix Banner Items.tmPreferences.cache
deleted file mode 100644
index c321af3..0000000
Binary files a/C++/Symbol List - Prefix Banner Items.tmPreferences.cache and /dev/null differ
diff --git a/CSS/CSS.tmLanguage.cache b/CSS/CSS.tmLanguage.cache
deleted file mode 100644
index 9e7c964..0000000
Binary files a/CSS/CSS.tmLanguage.cache and /dev/null differ
diff --git a/CSS/Comments.tmPreferences.cache b/CSS/Comments.tmPreferences.cache
deleted file mode 100644
index 740ab8b..0000000
Binary files a/CSS/Comments.tmPreferences.cache and /dev/null differ
diff --git a/CSS/Symbol List Group.tmPreferences.cache b/CSS/Symbol List Group.tmPreferences.cache
deleted file mode 100644
index 4557a38..0000000
Binary files a/CSS/Symbol List Group.tmPreferences.cache and /dev/null differ
diff --git a/CSS/Symbol List.tmPreferences.cache b/CSS/Symbol List.tmPreferences.cache
deleted file mode 100644
index a1caaed..0000000
Binary files a/CSS/Symbol List.tmPreferences.cache and /dev/null differ
diff --git a/Clojure/Clojure.tmLanguage.cache b/Clojure/Clojure.tmLanguage.cache
deleted file mode 100644
index d53e7fa..0000000
Binary files a/Clojure/Clojure.tmLanguage.cache and /dev/null differ
diff --git a/Clojure/Comment.tmPreferences.cache b/Clojure/Comment.tmPreferences.cache
deleted file mode 100644
index 164b6fc..0000000
Binary files a/Clojure/Comment.tmPreferences.cache and /dev/null differ
diff --git a/Clojure/Symbol List.tmPreferences.cache b/Clojure/Symbol List.tmPreferences.cache
deleted file mode 100644
index da742bf..0000000
Binary files a/Clojure/Symbol List.tmPreferences.cache and /dev/null differ
diff --git a/Color Scheme - Default/All Hallow's Eve.tmTheme.cache b/Color Scheme - Default/All Hallow's Eve.tmTheme.cache
deleted file mode 100644
index 509af32..0000000
Binary files a/Color Scheme - Default/All Hallow's Eve.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Amy.tmTheme.cache b/Color Scheme - Default/Amy.tmTheme.cache
deleted file mode 100644
index 63d1536..0000000
Binary files a/Color Scheme - Default/Amy.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Blackboard.tmTheme.cache b/Color Scheme - Default/Blackboard.tmTheme.cache
deleted file mode 100644
index 4f5cb10..0000000
Binary files a/Color Scheme - Default/Blackboard.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Cobalt.tmTheme.cache b/Color Scheme - Default/Cobalt.tmTheme.cache
deleted file mode 100644
index 88437d1..0000000
Binary files a/Color Scheme - Default/Cobalt.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Dawn.tmTheme.cache b/Color Scheme - Default/Dawn.tmTheme.cache
deleted file mode 100644
index b17078a..0000000
Binary files a/Color Scheme - Default/Dawn.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Eiffel.tmTheme.cache b/Color Scheme - Default/Eiffel.tmTheme.cache
deleted file mode 100644
index 37f2c07..0000000
Binary files a/Color Scheme - Default/Eiffel.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Espresso Libre.tmTheme.cache b/Color Scheme - Default/Espresso Libre.tmTheme.cache
deleted file mode 100644
index 9e09be9..0000000
Binary files a/Color Scheme - Default/Espresso Libre.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/IDLE.tmTheme.cache b/Color Scheme - Default/IDLE.tmTheme.cache
deleted file mode 100644
index 4cf30a4..0000000
Binary files a/Color Scheme - Default/IDLE.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/LAZY.tmTheme.cache b/Color Scheme - Default/LAZY.tmTheme.cache
deleted file mode 100644
index be82dd7..0000000
Binary files a/Color Scheme - Default/LAZY.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Mac Classic.tmTheme.cache b/Color Scheme - Default/Mac Classic.tmTheme.cache
deleted file mode 100644
index 5d91c95..0000000
Binary files a/Color Scheme - Default/Mac Classic.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/MagicWB (Amiga).tmTheme.cache b/Color Scheme - Default/MagicWB (Amiga).tmTheme.cache
deleted file mode 100644
index 2711e53..0000000
Binary files a/Color Scheme - Default/MagicWB (Amiga).tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Monokai Bright.tmTheme.cache b/Color Scheme - Default/Monokai Bright.tmTheme.cache
deleted file mode 100644
index f8e29e9..0000000
Binary files a/Color Scheme - Default/Monokai Bright.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Monokai.tmTheme.cache b/Color Scheme - Default/Monokai.tmTheme.cache
deleted file mode 100644
index b93f0e6..0000000
Binary files a/Color Scheme - Default/Monokai.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Pastels on Dark.tmTheme.cache b/Color Scheme - Default/Pastels on Dark.tmTheme.cache
deleted file mode 100644
index f0a2400..0000000
Binary files a/Color Scheme - Default/Pastels on Dark.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Slush & Poppies.tmTheme.cache b/Color Scheme - Default/Slush & Poppies.tmTheme.cache
deleted file mode 100644
index 94f345d..0000000
Binary files a/Color Scheme - Default/Slush & Poppies.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Solarized (Dark).tmTheme.cache b/Color Scheme - Default/Solarized (Dark).tmTheme.cache
deleted file mode 100644
index 3b5cb5c..0000000
Binary files a/Color Scheme - Default/Solarized (Dark).tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Solarized (Light).tmTheme.cache b/Color Scheme - Default/Solarized (Light).tmTheme.cache
deleted file mode 100644
index 511938b..0000000
Binary files a/Color Scheme - Default/Solarized (Light).tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/SpaceCadet.tmTheme.cache b/Color Scheme - Default/SpaceCadet.tmTheme.cache
deleted file mode 100644
index ebb2a43..0000000
Binary files a/Color Scheme - Default/SpaceCadet.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Sunburst.tmTheme.cache b/Color Scheme - Default/Sunburst.tmTheme.cache
deleted file mode 100644
index 8bb1ebf..0000000
Binary files a/Color Scheme - Default/Sunburst.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/Zenburnesque.tmTheme.cache b/Color Scheme - Default/Zenburnesque.tmTheme.cache
deleted file mode 100644
index dd7de4a..0000000
Binary files a/Color Scheme - Default/Zenburnesque.tmTheme.cache and /dev/null differ
diff --git a/Color Scheme - Default/iPlastic.tmTheme.cache b/Color Scheme - Default/iPlastic.tmTheme.cache
deleted file mode 100644
index 3cff790..0000000
Binary files a/Color Scheme - Default/iPlastic.tmTheme.cache and /dev/null differ
diff --git a/D/Comments.tmPreferences.cache b/D/Comments.tmPreferences.cache
deleted file mode 100644
index e728535..0000000
Binary files a/D/Comments.tmPreferences.cache and /dev/null differ
diff --git a/D/D.tmLanguage.cache b/D/D.tmLanguage.cache
deleted file mode 100644
index 49a6727..0000000
Binary files a/D/D.tmLanguage.cache and /dev/null differ
diff --git a/D/Indentation Rules.tmPreferences.cache b/D/Indentation Rules.tmPreferences.cache
deleted file mode 100644
index d7693db..0000000
Binary files a/D/Indentation Rules.tmPreferences.cache and /dev/null differ
diff --git a/D/Symbol List-Method-Constructor.tmPreferences.cache b/D/Symbol List-Method-Constructor.tmPreferences.cache
deleted file mode 100644
index 7dae094..0000000
Binary files a/D/Symbol List-Method-Constructor.tmPreferences.cache and /dev/null differ
diff --git a/Default/Find Results.hidden-tmLanguage.cache b/Default/Find Results.hidden-tmLanguage.cache
deleted file mode 100644
index 9afac60..0000000
Binary files a/Default/Find Results.hidden-tmLanguage.cache and /dev/null differ
diff --git a/Default/Ignored Packages.cache b/Default/Ignored Packages.cache
deleted file mode 100644
index 27b92a5..0000000
--- a/Default/Ignored Packages.cache
+++ /dev/null
@@ -1 +0,0 @@
-["Vintage"]
\ No newline at end of file
diff --git a/Default/Meta Info Summary.cache b/Default/Meta Info Summary.cache
deleted file mode 100644
index bc17893..0000000
Binary files a/Default/Meta Info Summary.cache and /dev/null differ
diff --git a/Default/Miscellaneous.tmPreferences.cache b/Default/Miscellaneous.tmPreferences.cache
deleted file mode 100644
index 886762a..0000000
Binary files a/Default/Miscellaneous.tmPreferences.cache and /dev/null differ
diff --git a/Default/Startup.cache b/Default/Startup.cache
deleted file mode 100644
index 58e7fec..0000000
Binary files a/Default/Startup.cache and /dev/null differ
diff --git a/Default/Symbol List.tmPreferences.cache b/Default/Symbol List.tmPreferences.cache
deleted file mode 100644
index 8ee76a7..0000000
Binary files a/Default/Symbol List.tmPreferences.cache and /dev/null differ
diff --git a/Default/Syntax Summary.cache b/Default/Syntax Summary.cache
deleted file mode 100644
index c37769e..0000000
Binary files a/Default/Syntax Summary.cache and /dev/null differ
diff --git a/Default/comment.pyc b/Default/comment.pyc
deleted file mode 100644
index ce0e14e..0000000
Binary files a/Default/comment.pyc and /dev/null differ
diff --git a/Default/copy_path.pyc b/Default/copy_path.pyc
deleted file mode 100644
index 790886a..0000000
Binary files a/Default/copy_path.pyc and /dev/null differ
diff --git a/Default/delete_word.pyc b/Default/delete_word.pyc
deleted file mode 100644
index f46354f..0000000
Binary files a/Default/delete_word.pyc and /dev/null differ
diff --git a/Default/detect_indentation.pyc b/Default/detect_indentation.pyc
deleted file mode 100644
index 45c82b0..0000000
Binary files a/Default/detect_indentation.pyc and /dev/null differ
diff --git a/Default/duplicate_line.pyc b/Default/duplicate_line.pyc
deleted file mode 100644
index b8d2e1a..0000000
Binary files a/Default/duplicate_line.pyc and /dev/null differ
diff --git a/Default/echo.pyc b/Default/echo.pyc
deleted file mode 100644
index 98d902e..0000000
Binary files a/Default/echo.pyc and /dev/null differ
diff --git a/Default/exec.pyc b/Default/exec.pyc
deleted file mode 100644
index e91a9e9..0000000
Binary files a/Default/exec.pyc and /dev/null differ
diff --git a/Default/find_under_expand.pyc b/Default/find_under_expand.pyc
deleted file mode 100644
index c451f6c..0000000
Binary files a/Default/find_under_expand.pyc and /dev/null differ
diff --git a/Default/fold.pyc b/Default/fold.pyc
deleted file mode 100644
index 6151797..0000000
Binary files a/Default/fold.pyc and /dev/null differ
diff --git a/Default/font.pyc b/Default/font.pyc
deleted file mode 100644
index cd8f7fe..0000000
Binary files a/Default/font.pyc and /dev/null differ
diff --git a/Default/goto_line.pyc b/Default/goto_line.pyc
deleted file mode 100644
index afbeeba..0000000
Binary files a/Default/goto_line.pyc and /dev/null differ
diff --git a/Default/indentation.pyc b/Default/indentation.pyc
deleted file mode 100644
index 8a7608b..0000000
Binary files a/Default/indentation.pyc and /dev/null differ
diff --git a/Default/kill_ring.pyc b/Default/kill_ring.pyc
deleted file mode 100644
index 526910d..0000000
Binary files a/Default/kill_ring.pyc and /dev/null differ
diff --git a/Default/mark.pyc b/Default/mark.pyc
deleted file mode 100644
index a0f8677..0000000
Binary files a/Default/mark.pyc and /dev/null differ
diff --git a/Default/new_templates.pyc b/Default/new_templates.pyc
deleted file mode 100644
index bed220b..0000000
Binary files a/Default/new_templates.pyc and /dev/null differ
diff --git a/Default/open_file_settings.pyc b/Default/open_file_settings.pyc
deleted file mode 100644
index 9d398ea..0000000
Binary files a/Default/open_file_settings.pyc and /dev/null differ
diff --git a/Default/paragraph.pyc b/Default/paragraph.pyc
deleted file mode 100644
index 2ed0c29..0000000
Binary files a/Default/paragraph.pyc and /dev/null differ
diff --git a/Default/save_on_focus_lost.pyc b/Default/save_on_focus_lost.pyc
deleted file mode 100644
index 1def175..0000000
Binary files a/Default/save_on_focus_lost.pyc and /dev/null differ
diff --git a/Default/scroll.pyc b/Default/scroll.pyc
deleted file mode 100644
index ee8fa53..0000000
Binary files a/Default/scroll.pyc and /dev/null differ
diff --git a/Default/send2trash/__init__.pyc b/Default/send2trash/__init__.pyc
deleted file mode 100644
index f13ca9c..0000000
Binary files a/Default/send2trash/__init__.pyc and /dev/null differ
diff --git a/Default/send2trash/plat_win.pyc b/Default/send2trash/plat_win.pyc
deleted file mode 100644
index 3383dd6..0000000
Binary files a/Default/send2trash/plat_win.pyc and /dev/null differ
diff --git a/Default/side_bar.pyc b/Default/side_bar.pyc
deleted file mode 100644
index 916b65d..0000000
Binary files a/Default/side_bar.pyc and /dev/null differ
diff --git a/Default/sort.pyc b/Default/sort.pyc
deleted file mode 100644
index 87f3b64..0000000
Binary files a/Default/sort.pyc and /dev/null differ
diff --git a/Default/swap_line.pyc b/Default/swap_line.pyc
deleted file mode 100644
index 639361b..0000000
Binary files a/Default/swap_line.pyc and /dev/null differ
diff --git a/Default/switch_file.pyc b/Default/switch_file.pyc
deleted file mode 100644
index 861860f..0000000
Binary files a/Default/switch_file.pyc and /dev/null differ
diff --git a/Default/transform.pyc b/Default/transform.pyc
deleted file mode 100644
index 591c31c..0000000
Binary files a/Default/transform.pyc and /dev/null differ
diff --git a/Default/transpose.pyc b/Default/transpose.pyc
deleted file mode 100644
index a3e467f..0000000
Binary files a/Default/transpose.pyc and /dev/null differ
diff --git a/Default/trim_trailing_white_space.pyc b/Default/trim_trailing_white_space.pyc
deleted file mode 100644
index 3ab1160..0000000
Binary files a/Default/trim_trailing_white_space.pyc and /dev/null differ
diff --git a/Diff/Diff.tmLanguage.cache b/Diff/Diff.tmLanguage.cache
deleted file mode 100644
index 48958fd..0000000
Binary files a/Diff/Diff.tmLanguage.cache and /dev/null differ
diff --git a/Diff/diff.pyc b/Diff/diff.pyc
deleted file mode 100644
index ff83e1d..0000000
Binary files a/Diff/diff.pyc and /dev/null differ
diff --git a/Drupal Snippets/package-metadata.json b/Drupal Snippets/package-metadata.json
index e8fea20..f9c1b18 100644
--- a/Drupal Snippets/package-metadata.json
+++ b/Drupal Snippets/package-metadata.json
@@ -1 +1 @@
-{"url": "https://github.com/juhasz/drupal_sublime-snippets", "version": "2012.01.22.20.31.41", "description": "Drupal snippets for Sublime Editor, converted from Vim snipMate drupal-snippets"}
\ No newline at end of file
+{"url": "https://github.com/juhasz/drupal_sublime-snippets", "version": "2012.01.22.23.31.41", "description": "Drupal snippets for Sublime Editor, converted from Vim snipMate drupal-snippets"}
\ No newline at end of file
diff --git a/Erlang/Comments.tmPreferences.cache b/Erlang/Comments.tmPreferences.cache
deleted file mode 100644
index 72dd0cc..0000000
Binary files a/Erlang/Comments.tmPreferences.cache and /dev/null differ
diff --git a/Erlang/Erlang.tmLanguage.cache b/Erlang/Erlang.tmLanguage.cache
deleted file mode 100644
index b2e06dd..0000000
Binary files a/Erlang/Erlang.tmLanguage.cache and /dev/null differ
diff --git a/Erlang/Function Symbols.tmPreferences.cache b/Erlang/Function Symbols.tmPreferences.cache
deleted file mode 100644
index b087f55..0000000
Binary files a/Erlang/Function Symbols.tmPreferences.cache and /dev/null differ
diff --git a/Erlang/HTML (Erlang).tmLanguage.cache b/Erlang/HTML (Erlang).tmLanguage.cache
deleted file mode 100644
index 64fd925..0000000
Binary files a/Erlang/HTML (Erlang).tmLanguage.cache and /dev/null differ
diff --git a/Erlang/Indentation Rules.tmPreferences.cache b/Erlang/Indentation Rules.tmPreferences.cache
deleted file mode 100644
index ae87a09..0000000
Binary files a/Erlang/Indentation Rules.tmPreferences.cache and /dev/null differ
diff --git a/Erlang/Macro Symbols.tmPreferences.cache b/Erlang/Macro Symbols.tmPreferences.cache
deleted file mode 100644
index b72d70c..0000000
Binary files a/Erlang/Macro Symbols.tmPreferences.cache and /dev/null differ
diff --git a/Erlang/Module Symbols.tmPreferences.cache b/Erlang/Module Symbols.tmPreferences.cache
deleted file mode 100644
index adc29d9..0000000
Binary files a/Erlang/Module Symbols.tmPreferences.cache and /dev/null differ
diff --git a/Erlang/Record Symbols.tmPreferences.cache b/Erlang/Record Symbols.tmPreferences.cache
deleted file mode 100644
index 10bb8b5..0000000
Binary files a/Erlang/Record Symbols.tmPreferences.cache and /dev/null differ
diff --git a/Erlang/Symbol Overrides.tmPreferences.cache b/Erlang/Symbol Overrides.tmPreferences.cache
deleted file mode 100644
index 4ffe2c8..0000000
Binary files a/Erlang/Symbol Overrides.tmPreferences.cache and /dev/null differ
diff --git a/Go/Comments.tmPreferences.cache b/Go/Comments.tmPreferences.cache
deleted file mode 100644
index e3dae2d..0000000
Binary files a/Go/Comments.tmPreferences.cache and /dev/null differ
diff --git a/Go/Go.tmLanguage.cache b/Go/Go.tmLanguage.cache
deleted file mode 100644
index 0e3d391..0000000
Binary files a/Go/Go.tmLanguage.cache and /dev/null differ
diff --git a/Go/Indentation Rules.tmPreferences.cache b/Go/Indentation Rules.tmPreferences.cache
deleted file mode 100644
index 76fa6b4..0000000
Binary files a/Go/Indentation Rules.tmPreferences.cache and /dev/null differ
diff --git a/Graphviz/DOT.tmLanguage.cache b/Graphviz/DOT.tmLanguage.cache
deleted file mode 100644
index 5b1240e..0000000
Binary files a/Graphviz/DOT.tmLanguage.cache and /dev/null differ
diff --git a/Groovy/Groovy.tmLanguage.cache b/Groovy/Groovy.tmLanguage.cache
deleted file mode 100644
index 735653c..0000000
Binary files a/Groovy/Groovy.tmLanguage.cache and /dev/null differ
diff --git a/Groovy/Symbol List%3A Class Variables.tmPreferences.cache b/Groovy/Symbol List%3A Class Variables.tmPreferences.cache
deleted file mode 100644
index 6938ba9..0000000
Binary files a/Groovy/Symbol List%3A Class Variables.tmPreferences.cache and /dev/null differ
diff --git a/Groovy/Symbol List%3A Classes.tmPreferences.cache b/Groovy/Symbol List%3A Classes.tmPreferences.cache
deleted file mode 100644
index 983e8b3..0000000
Binary files a/Groovy/Symbol List%3A Classes.tmPreferences.cache and /dev/null differ
diff --git a/Groovy/Symbol List%3A Methods.tmPreferences.cache b/Groovy/Symbol List%3A Methods.tmPreferences.cache
deleted file mode 100644
index f3a253c..0000000
Binary files a/Groovy/Symbol List%3A Methods.tmPreferences.cache and /dev/null differ
diff --git a/Groovy/Symbol List%3A Variables.tmPreferences.cache b/Groovy/Symbol List%3A Variables.tmPreferences.cache
deleted file mode 100644
index bd33a52..0000000
Binary files a/Groovy/Symbol List%3A Variables.tmPreferences.cache and /dev/null differ
diff --git a/HTML/Comments.tmPreferences.cache b/HTML/Comments.tmPreferences.cache
deleted file mode 100644
index 3e18286..0000000
Binary files a/HTML/Comments.tmPreferences.cache and /dev/null differ
diff --git a/HTML/HTML.tmLanguage.cache b/HTML/HTML.tmLanguage.cache
deleted file mode 100644
index ce6b94c..0000000
Binary files a/HTML/HTML.tmLanguage.cache and /dev/null differ
diff --git a/HTML/Symbol List - ID.tmPreferences.cache b/HTML/Symbol List - ID.tmPreferences.cache
deleted file mode 100644
index 246c870..0000000
Binary files a/HTML/Symbol List - ID.tmPreferences.cache and /dev/null differ
diff --git a/HTML/encode_html_entities.pyc b/HTML/encode_html_entities.pyc
deleted file mode 100644
index a171985..0000000
Binary files a/HTML/encode_html_entities.pyc and /dev/null differ
diff --git a/HTML/html_completions.pyc b/HTML/html_completions.pyc
deleted file mode 100644
index 98dd2bf..0000000
Binary files a/HTML/html_completions.pyc and /dev/null differ
diff --git a/Haskell/Comments.tmPreferences.cache b/Haskell/Comments.tmPreferences.cache
deleted file mode 100644
index fb75b7e..0000000
Binary files a/Haskell/Comments.tmPreferences.cache and /dev/null differ
diff --git a/Haskell/Haskell.tmLanguage.cache b/Haskell/Haskell.tmLanguage.cache
deleted file mode 100644
index 803814e..0000000
Binary files a/Haskell/Haskell.tmLanguage.cache and /dev/null differ
diff --git a/Haskell/Indent Patterns.tmPreferences.cache b/Haskell/Indent Patterns.tmPreferences.cache
deleted file mode 100644
index 1d82332..0000000
Binary files a/Haskell/Indent Patterns.tmPreferences.cache and /dev/null differ
diff --git a/Haskell/Literate Haskell.tmLanguage.cache b/Haskell/Literate Haskell.tmLanguage.cache
deleted file mode 100644
index 085a694..0000000
Binary files a/Haskell/Literate Haskell.tmLanguage.cache and /dev/null differ
diff --git a/Haskell/Symbol List.tmPreferences.cache b/Haskell/Symbol List.tmPreferences.cache
deleted file mode 100644
index 067fd06..0000000
Binary files a/Haskell/Symbol List.tmPreferences.cache and /dev/null differ
diff --git a/Java/Comments.tmPreferences.cache b/Java/Comments.tmPreferences.cache
deleted file mode 100644
index 842b0b5..0000000
Binary files a/Java/Comments.tmPreferences.cache and /dev/null differ
diff --git a/Java/Indentation Rules.tmPreferences.cache b/Java/Indentation Rules.tmPreferences.cache
deleted file mode 100644
index f005cc5..0000000
Binary files a/Java/Indentation Rules.tmPreferences.cache and /dev/null differ
diff --git a/Java/Java Server Pages (JSP).tmLanguage.cache b/Java/Java Server Pages (JSP).tmLanguage.cache
deleted file mode 100644
index 875d2b6..0000000
Binary files a/Java/Java Server Pages (JSP).tmLanguage.cache and /dev/null differ
diff --git a/Java/Java.tmLanguage.cache b/Java/Java.tmLanguage.cache
deleted file mode 100644
index e04ddfd..0000000
Binary files a/Java/Java.tmLanguage.cache and /dev/null differ
diff --git a/Java/JavaDoc.tmLanguage.cache b/Java/JavaDoc.tmLanguage.cache
deleted file mode 100644
index 5f237e5..0000000
Binary files a/Java/JavaDoc.tmLanguage.cache and /dev/null differ
diff --git a/Java/JavaProperties.tmLanguage.cache b/Java/JavaProperties.tmLanguage.cache
deleted file mode 100644
index ceea5aa..0000000
Binary files a/Java/JavaProperties.tmLanguage.cache and /dev/null differ
diff --git a/Java/Symbol List%3A Classes.tmPreferences.cache b/Java/Symbol List%3A Classes.tmPreferences.cache
deleted file mode 100644
index 786170c..0000000
Binary files a/Java/Symbol List%3A Classes.tmPreferences.cache and /dev/null differ
diff --git a/Java/Symbol List%3A Inner Class Methods.tmPreferences.cache b/Java/Symbol List%3A Inner Class Methods.tmPreferences.cache
deleted file mode 100644
index 5497bbe..0000000
Binary files a/Java/Symbol List%3A Inner Class Methods.tmPreferences.cache and /dev/null differ
diff --git a/Java/Symbol List%3A Inner Classes.tmPreferences.cache b/Java/Symbol List%3A Inner Classes.tmPreferences.cache
deleted file mode 100644
index 1d04b5a..0000000
Binary files a/Java/Symbol List%3A Inner Classes.tmPreferences.cache and /dev/null differ
diff --git a/Java/Symbol List%3A Inner Inner Class Methods.tmPreferences.cache b/Java/Symbol List%3A Inner Inner Class Methods.tmPreferences.cache
deleted file mode 100644
index 3999fbf..0000000
Binary files a/Java/Symbol List%3A Inner Inner Class Methods.tmPreferences.cache and /dev/null differ
diff --git a/Java/Symbol List%3A Inner Inner Classes.tmPreferences.cache b/Java/Symbol List%3A Inner Inner Classes.tmPreferences.cache
deleted file mode 100644
index d1ff68a..0000000
Binary files a/Java/Symbol List%3A Inner Inner Classes.tmPreferences.cache and /dev/null differ
diff --git a/Java/Symbol List%3A Method.tmPreferences.cache b/Java/Symbol List%3A Method.tmPreferences.cache
deleted file mode 100644
index 3a7a179..0000000
Binary files a/Java/Symbol List%3A Method.tmPreferences.cache and /dev/null differ
diff --git a/JavaScript/Comments.tmPreferences.cache b/JavaScript/Comments.tmPreferences.cache
deleted file mode 100644
index bba47b6..0000000
Binary files a/JavaScript/Comments.tmPreferences.cache and /dev/null differ
diff --git a/JavaScript/JSON.tmLanguage.cache b/JavaScript/JSON.tmLanguage.cache
deleted file mode 100644
index c2a42dc..0000000
Binary files a/JavaScript/JSON.tmLanguage.cache and /dev/null differ
diff --git a/JavaScript/JavaScript Indent.tmPreferences.cache b/JavaScript/JavaScript Indent.tmPreferences.cache
deleted file mode 100644
index c482a57..0000000
Binary files a/JavaScript/JavaScript Indent.tmPreferences.cache and /dev/null differ
diff --git a/JavaScript/JavaScript.tmLanguage.cache b/JavaScript/JavaScript.tmLanguage.cache
deleted file mode 100644
index fbe3d1d..0000000
Binary files a/JavaScript/JavaScript.tmLanguage.cache and /dev/null differ
diff --git a/JavaScript/Symbol List Banned.tmPreferences.cache b/JavaScript/Symbol List Banned.tmPreferences.cache
deleted file mode 100644
index 65943ec..0000000
Binary files a/JavaScript/Symbol List Banned.tmPreferences.cache and /dev/null differ
diff --git a/JavaScript/Symbol List Class.tmPreferences.cache b/JavaScript/Symbol List Class.tmPreferences.cache
deleted file mode 100644
index d31e750..0000000
Binary files a/JavaScript/Symbol List Class.tmPreferences.cache and /dev/null differ
diff --git a/JavaScript/Symbol List Function.tmPreferences.cache b/JavaScript/Symbol List Function.tmPreferences.cache
deleted file mode 100644
index f48a04b..0000000
Binary files a/JavaScript/Symbol List Function.tmPreferences.cache and /dev/null differ
diff --git a/JavaScript/Symbol List Instance.tmPreferences.cache b/JavaScript/Symbol List Instance.tmPreferences.cache
deleted file mode 100644
index 7fb6c88..0000000
Binary files a/JavaScript/Symbol List Instance.tmPreferences.cache and /dev/null differ
diff --git a/JavaScript/Symbol List Sub 1.tmPreferences.cache b/JavaScript/Symbol List Sub 1.tmPreferences.cache
deleted file mode 100644
index 94d526e..0000000
Binary files a/JavaScript/Symbol List Sub 1.tmPreferences.cache and /dev/null differ
diff --git a/JavaScript/Symbol List Sub 2.tmPreferences.cache b/JavaScript/Symbol List Sub 2.tmPreferences.cache
deleted file mode 100644
index 2a1b7c3..0000000
Binary files a/JavaScript/Symbol List Sub 2.tmPreferences.cache and /dev/null differ
diff --git a/LaTeX/Bibtex.tmLanguage.cache b/LaTeX/Bibtex.tmLanguage.cache
deleted file mode 100644
index 620eb7a..0000000
Binary files a/LaTeX/Bibtex.tmLanguage.cache and /dev/null differ
diff --git a/LaTeX/Comments.tmPreferences.cache b/LaTeX/Comments.tmPreferences.cache
deleted file mode 100644
index 34b9944..0000000
Binary files a/LaTeX/Comments.tmPreferences.cache and /dev/null differ
diff --git a/LaTeX/LaTeX Beamer.tmLanguage.cache b/LaTeX/LaTeX Beamer.tmLanguage.cache
deleted file mode 100644
index 2f3eec9..0000000
Binary files a/LaTeX/LaTeX Beamer.tmLanguage.cache and /dev/null differ
diff --git a/LaTeX/LaTeX Log.tmLanguage.cache b/LaTeX/LaTeX Log.tmLanguage.cache
deleted file mode 100644
index 71eb94f..0000000
Binary files a/LaTeX/LaTeX Log.tmLanguage.cache and /dev/null differ
diff --git a/LaTeX/LaTeX Memoir.tmLanguage.cache b/LaTeX/LaTeX Memoir.tmLanguage.cache
deleted file mode 100644
index 3e936b5..0000000
Binary files a/LaTeX/LaTeX Memoir.tmLanguage.cache and /dev/null differ
diff --git a/LaTeX/LaTeX.tmLanguage.cache b/LaTeX/LaTeX.tmLanguage.cache
deleted file mode 100644
index 2448941..0000000
Binary files a/LaTeX/LaTeX.tmLanguage.cache and /dev/null differ
diff --git a/LaTeX/TeX Math.tmLanguage.cache b/LaTeX/TeX Math.tmLanguage.cache
deleted file mode 100644
index 09651af..0000000
Binary files a/LaTeX/TeX Math.tmLanguage.cache and /dev/null differ
diff --git a/LaTeX/TeX.tmLanguage.cache b/LaTeX/TeX.tmLanguage.cache
deleted file mode 100644
index 9ef4cd4..0000000
Binary files a/LaTeX/TeX.tmLanguage.cache and /dev/null differ
diff --git a/Lisp/Comments.tmPreferences.cache b/Lisp/Comments.tmPreferences.cache
deleted file mode 100644
index 2001b7f..0000000
Binary files a/Lisp/Comments.tmPreferences.cache and /dev/null differ
diff --git a/Lisp/Lisp.tmLanguage.cache b/Lisp/Lisp.tmLanguage.cache
deleted file mode 100644
index dff53cc..0000000
Binary files a/Lisp/Lisp.tmLanguage.cache and /dev/null differ
diff --git a/Lua/Comments.tmPreferences.cache b/Lua/Comments.tmPreferences.cache
deleted file mode 100644
index 7391fbd..0000000
Binary files a/Lua/Comments.tmPreferences.cache and /dev/null differ
diff --git a/Lua/Indent.tmPreferences.cache b/Lua/Indent.tmPreferences.cache
deleted file mode 100644
index 8fd9e32..0000000
Binary files a/Lua/Indent.tmPreferences.cache and /dev/null differ
diff --git a/Lua/Lua.tmLanguage.cache b/Lua/Lua.tmLanguage.cache
deleted file mode 100644
index b9cdb7f..0000000
Binary files a/Lua/Lua.tmLanguage.cache and /dev/null differ
diff --git a/Makefile/Makefile.tmLanguage.cache b/Makefile/Makefile.tmLanguage.cache
deleted file mode 100644
index d71a79f..0000000
Binary files a/Makefile/Makefile.tmLanguage.cache and /dev/null differ
diff --git a/Makefile/Miscellaneous.tmPreferences.cache b/Makefile/Miscellaneous.tmPreferences.cache
deleted file mode 100644
index 41e4ea1..0000000
Binary files a/Makefile/Miscellaneous.tmPreferences.cache and /dev/null differ
diff --git a/Markdown/Indent%3A Raw.tmPreferences.cache b/Markdown/Indent%3A Raw.tmPreferences.cache
deleted file mode 100644
index 47ae0c6..0000000
Binary files a/Markdown/Indent%3A Raw.tmPreferences.cache and /dev/null differ
diff --git a/Markdown/Markdown.tmLanguage.cache b/Markdown/Markdown.tmLanguage.cache
deleted file mode 100644
index e384d76..0000000
Binary files a/Markdown/Markdown.tmLanguage.cache and /dev/null differ
diff --git a/Markdown/MultiMarkdown.tmLanguage.cache b/Markdown/MultiMarkdown.tmLanguage.cache
deleted file mode 100644
index cbbe61c..0000000
Binary files a/Markdown/MultiMarkdown.tmLanguage.cache and /dev/null differ
diff --git a/Markdown/Symbol List - Heading.tmPreferences.cache b/Markdown/Symbol List - Heading.tmPreferences.cache
deleted file mode 100644
index 4f9c518..0000000
Binary files a/Markdown/Symbol List - Heading.tmPreferences.cache and /dev/null differ
diff --git a/Matlab/Indent.tmPreferences.cache b/Matlab/Indent.tmPreferences.cache
deleted file mode 100644
index d6cb677..0000000
Binary files a/Matlab/Indent.tmPreferences.cache and /dev/null differ
diff --git a/Matlab/Matlab.tmLanguage.cache b/Matlab/Matlab.tmLanguage.cache
deleted file mode 100644
index 2fd3fa2..0000000
Binary files a/Matlab/Matlab.tmLanguage.cache and /dev/null differ
diff --git a/Matlab/Miscellaneous.tmPreferences.cache b/Matlab/Miscellaneous.tmPreferences.cache
deleted file mode 100644
index 8721b6b..0000000
Binary files a/Matlab/Miscellaneous.tmPreferences.cache and /dev/null differ
diff --git a/Matlab/Symbols.tmPreferences.cache b/Matlab/Symbols.tmPreferences.cache
deleted file mode 100644
index 1bc5028..0000000
Binary files a/Matlab/Symbols.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Indent rules.tmPreferences.cache b/OCaml/Indent rules.tmPreferences.cache
deleted file mode 100644
index 4c83e41..0000000
Binary files a/OCaml/Indent rules.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Miscellaneous.tmPreferences.cache b/OCaml/Miscellaneous.tmPreferences.cache
deleted file mode 100644
index 48e0d22..0000000
Binary files a/OCaml/Miscellaneous.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/OCaml.tmLanguage.cache b/OCaml/OCaml.tmLanguage.cache
deleted file mode 100644
index b6dc816..0000000
Binary files a/OCaml/OCaml.tmLanguage.cache and /dev/null differ
diff --git a/OCaml/OCamllex.tmLanguage.cache b/OCaml/OCamllex.tmLanguage.cache
deleted file mode 100644
index 231696b..0000000
Binary files a/OCaml/OCamllex.tmLanguage.cache and /dev/null differ
diff --git a/OCaml/OCamlyacc.tmLanguage.cache b/OCaml/OCamlyacc.tmLanguage.cache
deleted file mode 100644
index db3658d..0000000
Binary files a/OCaml/OCamlyacc.tmLanguage.cache and /dev/null differ
diff --git a/OCaml/Symbol List%3A Classes.tmPreferences.cache b/OCaml/Symbol List%3A Classes.tmPreferences.cache
deleted file mode 100644
index 9765886..0000000
Binary files a/OCaml/Symbol List%3A Classes.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List%3A Exceptions.tmPreferences.cache b/OCaml/Symbol List%3A Exceptions.tmPreferences.cache
deleted file mode 100644
index b6c322e..0000000
Binary files a/OCaml/Symbol List%3A Exceptions.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List%3A Ocamllex pattern definition.tmPreferences.cache b/OCaml/Symbol List%3A Ocamllex pattern definition.tmPreferences.cache
deleted file mode 100644
index bb289c8..0000000
Binary files a/OCaml/Symbol List%3A Ocamllex pattern definition.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List%3A Ocamllex pattern references.tmPreferences.cache b/OCaml/Symbol List%3A Ocamllex pattern references.tmPreferences.cache
deleted file mode 100644
index 1c47040..0000000
Binary files a/OCaml/Symbol List%3A Ocamllex pattern references.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List%3A Ocamllex rules.tmPreferences.cache b/OCaml/Symbol List%3A Ocamllex rules.tmPreferences.cache
deleted file mode 100644
index fc804da..0000000
Binary files a/OCaml/Symbol List%3A Ocamllex rules.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List%3A Ocamlyacc non-terminal definition.tmPreferences.cache b/OCaml/Symbol List%3A Ocamlyacc non-terminal definition.tmPreferences.cache
deleted file mode 100644
index 73e776c..0000000
Binary files a/OCaml/Symbol List%3A Ocamlyacc non-terminal definition.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List%3A Ocamlyacc non-terminal reference.tmPreferences.cache b/OCaml/Symbol List%3A Ocamlyacc non-terminal reference.tmPreferences.cache
deleted file mode 100644
index e33aca9..0000000
Binary files a/OCaml/Symbol List%3A Ocamlyacc non-terminal reference.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List%3A Ocamlyacc token definition.tmPreferences.cache b/OCaml/Symbol List%3A Ocamlyacc token definition.tmPreferences.cache
deleted file mode 100644
index c229152..0000000
Binary files a/OCaml/Symbol List%3A Ocamlyacc token definition.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List%3A Ocamlyacc token reference.tmPreferences.cache b/OCaml/Symbol List%3A Ocamlyacc token reference.tmPreferences.cache
deleted file mode 100644
index e0c326d..0000000
Binary files a/OCaml/Symbol List%3A Ocamlyacc token reference.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List%3A Types.tmPreferences.cache b/OCaml/Symbol List%3A Types.tmPreferences.cache
deleted file mode 100644
index 68208bb..0000000
Binary files a/OCaml/Symbol List%3A Types.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List%3A Variants.tmPreferences.cache b/OCaml/Symbol List%3A Variants.tmPreferences.cache
deleted file mode 100644
index 5a3bd12..0000000
Binary files a/OCaml/Symbol List%3A Variants.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List_ Classes.tmPreferences.cache b/OCaml/Symbol List_ Classes.tmPreferences.cache
deleted file mode 100644
index 9765886..0000000
Binary files a/OCaml/Symbol List_ Classes.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List_ Exceptions.tmPreferences.cache b/OCaml/Symbol List_ Exceptions.tmPreferences.cache
deleted file mode 100644
index b6c322e..0000000
Binary files a/OCaml/Symbol List_ Exceptions.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List_ Ocamllex pattern definition.tmPreferences.cache b/OCaml/Symbol List_ Ocamllex pattern definition.tmPreferences.cache
deleted file mode 100644
index bb289c8..0000000
Binary files a/OCaml/Symbol List_ Ocamllex pattern definition.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List_ Ocamllex pattern references.tmPreferences.cache b/OCaml/Symbol List_ Ocamllex pattern references.tmPreferences.cache
deleted file mode 100644
index 1c47040..0000000
Binary files a/OCaml/Symbol List_ Ocamllex pattern references.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List_ Ocamllex rules.tmPreferences.cache b/OCaml/Symbol List_ Ocamllex rules.tmPreferences.cache
deleted file mode 100644
index fc804da..0000000
Binary files a/OCaml/Symbol List_ Ocamllex rules.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List_ Ocamlyacc non-terminal definition.tmPreferences.cache b/OCaml/Symbol List_ Ocamlyacc non-terminal definition.tmPreferences.cache
deleted file mode 100644
index 73e776c..0000000
Binary files a/OCaml/Symbol List_ Ocamlyacc non-terminal definition.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List_ Ocamlyacc non-terminal reference.tmPreferences.cache b/OCaml/Symbol List_ Ocamlyacc non-terminal reference.tmPreferences.cache
deleted file mode 100644
index e33aca9..0000000
Binary files a/OCaml/Symbol List_ Ocamlyacc non-terminal reference.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List_ Ocamlyacc token definition.tmPreferences.cache b/OCaml/Symbol List_ Ocamlyacc token definition.tmPreferences.cache
deleted file mode 100644
index c229152..0000000
Binary files a/OCaml/Symbol List_ Ocamlyacc token definition.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List_ Ocamlyacc token reference.tmPreferences.cache b/OCaml/Symbol List_ Ocamlyacc token reference.tmPreferences.cache
deleted file mode 100644
index e0c326d..0000000
Binary files a/OCaml/Symbol List_ Ocamlyacc token reference.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List_ Types.tmPreferences.cache b/OCaml/Symbol List_ Types.tmPreferences.cache
deleted file mode 100644
index 68208bb..0000000
Binary files a/OCaml/Symbol List_ Types.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/Symbol List_ Variants.tmPreferences.cache b/OCaml/Symbol List_ Variants.tmPreferences.cache
deleted file mode 100644
index 5a3bd12..0000000
Binary files a/OCaml/Symbol List_ Variants.tmPreferences.cache and /dev/null differ
diff --git a/OCaml/camlp4.tmLanguage.cache b/OCaml/camlp4.tmLanguage.cache
deleted file mode 100644
index ff105b3..0000000
Binary files a/OCaml/camlp4.tmLanguage.cache and /dev/null differ
diff --git a/Objective-C/Objective-C++.tmLanguage.cache b/Objective-C/Objective-C++.tmLanguage.cache
deleted file mode 100644
index 59a9dd7..0000000
Binary files a/Objective-C/Objective-C++.tmLanguage.cache and /dev/null differ
diff --git a/Objective-C/Objective-C.tmLanguage.cache b/Objective-C/Objective-C.tmLanguage.cache
deleted file mode 100644
index efdea82..0000000
Binary files a/Objective-C/Objective-C.tmLanguage.cache and /dev/null differ
diff --git a/PHP/Comments.tmPreferences.cache b/PHP/Comments.tmPreferences.cache
deleted file mode 100644
index c6c07b7..0000000
Binary files a/PHP/Comments.tmPreferences.cache and /dev/null differ
diff --git a/PHP/Indentation Rules.tmPreferences.cache b/PHP/Indentation Rules.tmPreferences.cache
deleted file mode 100644
index 6630103..0000000
Binary files a/PHP/Indentation Rules.tmPreferences.cache and /dev/null differ
diff --git a/PHP/PHP.tmLanguage.cache b/PHP/PHP.tmLanguage.cache
deleted file mode 100644
index e1e8214..0000000
Binary files a/PHP/PHP.tmLanguage.cache and /dev/null differ
diff --git a/PHP/Symbol List.tmPreferences.cache b/PHP/Symbol List.tmPreferences.cache
deleted file mode 100644
index 092762f..0000000
Binary files a/PHP/Symbol List.tmPreferences.cache and /dev/null differ
diff --git a/Package Control/Default.sublime-commands b/Package Control/Default.sublime-commands
index 84be427..7d823ee 100644
--- a/Package Control/Default.sublime-commands
+++ b/Package Control/Default.sublime-commands
@@ -4,7 +4,7 @@
"command": "add_repository"
},
{
- "caption": "Package Control: Add Repository Channel",
+ "caption": "Package Control: Add Channel",
"command": "add_repository_channel"
},
{
diff --git a/Package Control/Package Control.py b/Package Control/Package Control.py
index db838df..5994d70 100644
--- a/Package Control/Package Control.py
+++ b/Package Control/Package Control.py
@@ -8,7 +8,7 @@
import urllib
import urllib2
import json
-import fnmatch
+from fnmatch import fnmatch
import re
import threading
import datetime
@@ -19,6 +19,85 @@
try:
import ssl
+ import httplib
+ import socket
+
+ class InvalidCertificateException(httplib.HTTPException, urllib2.URLError):
+ def __init__(self, host, cert, reason):
+ httplib.HTTPException.__init__(self)
+ self.host = host
+ self.cert = cert
+ self.reason = reason
+
+ def __str__(self):
+ return ('Host %s returned an invalid certificate (%s) %s\n' %
+ (self.host, self.reason, self.cert))
+
+ class CertValidatingHTTPSConnection(httplib.HTTPConnection):
+ default_port = httplib.HTTPS_PORT
+
+ def __init__(self, host, port=None, key_file=None, cert_file=None,
+ ca_certs=None, strict=None, **kwargs):
+ httplib.HTTPConnection.__init__(self, host, port, strict, **kwargs)
+ self.key_file = key_file
+ self.cert_file = cert_file
+ self.ca_certs = ca_certs
+ if self.ca_certs:
+ self.cert_reqs = ssl.CERT_REQUIRED
+ else:
+ self.cert_reqs = ssl.CERT_NONE
+
+ def _GetValidHostsForCert(self, cert):
+ if 'subjectAltName' in cert:
+ return [x[1] for x in cert['subjectAltName']
+ if x[0].lower() == 'dns']
+ else:
+ return [x[0][1] for x in cert['subject']
+ if x[0][0].lower() == 'commonname']
+
+ def _ValidateCertificateHostname(self, cert, hostname):
+ hosts = self._GetValidHostsForCert(cert)
+ for host in hosts:
+ host_re = host.replace('.', '\.').replace('*', '[^.]*')
+ if re.search('^%s$' % (host_re,), hostname, re.I):
+ return True
+ return False
+
+ def connect(self):
+ sock = socket.create_connection((self.host, self.port))
+ self.sock = ssl.wrap_socket(sock, keyfile=self.key_file,
+ certfile=self.cert_file,
+ cert_reqs=self.cert_reqs,
+ ca_certs=self.ca_certs)
+ if self.cert_reqs & ssl.CERT_REQUIRED:
+ cert = self.sock.getpeercert()
+ hostname = self.host.split(':', 0)[0]
+ if not self._ValidateCertificateHostname(cert, hostname):
+ raise InvalidCertificateException(hostname, cert,
+ 'hostname mismatch')
+
+ if hasattr(urllib2, 'HTTPSHandler'):
+ class VerifiedHTTPSHandler(urllib2.HTTPSHandler):
+ def __init__(self, **kwargs):
+ urllib2.AbstractHTTPHandler.__init__(self)
+ self._connection_args = kwargs
+
+ def https_open(self, req):
+ def http_class_wrapper(host, **kwargs):
+ full_kwargs = dict(self._connection_args)
+ full_kwargs.update(kwargs)
+ return CertValidatingHTTPSConnection(host, **full_kwargs)
+
+ try:
+ return self.do_open(http_class_wrapper, req)
+ except urllib2.URLError, e:
+ if type(e.reason) == ssl.SSLError and e.reason.args[0] == 1:
+ raise InvalidCertificateException(req.host, '',
+ e.reason.args[1])
+ raise
+
+ https_request = urllib2.HTTPSHandler.do_request_
+
except (ImportError):
pass
@@ -74,8 +153,8 @@ def fetch_channel(self):
try:
channel_info = json.loads(channel_json)
except (ValueError):
- sublime.error_message(__name__ + ': Error parsing JSON from ' +
- ' channel ' + self.channel + '.')
+ sublime.error_message(('%s: Error parsing JSON from ' +
+ 'channel %s.') % (__name__, self.channel))
channel_info = False
self.channel_info = channel_info
@@ -98,6 +177,12 @@ def get_repositories(self):
return False
return self.channel_info['repositories']
+ def get_certs(self):
+ self.fetch_channel()
+ if self.channel_info == False:
+ return False
+ return self.channel_info.get('certs', {})
+
def get_packages(self, repo):
self.fetch_channel()
if self.channel_info == False:
@@ -151,8 +236,8 @@ def fetch_repo(self):
try:
self.repo_info = json.loads(repository_json)
except (ValueError):
- sublime.error_message(__name__ + ': Error parsing JSON from ' +
- ' repository ' + self.repo + '.')
+ sublime.error_message(('%s: Error parsing JSON from ' +
+ 'repository %s.') % (__name__, self.repo))
self.repo_info = False
def get_packages(self):
@@ -219,8 +304,8 @@ def get_packages(self):
try:
repo_info = json.loads(repo_json)
except (ValueError):
- sublime.error_message(__name__ + ': Error parsing JSON from ' +
- ' repository ' + api_url + '.')
+ sublime.error_message(('%s: Error parsing JSON from ' +
+ 'repository %s.') % (__name__, api_url))
return False
commit_api_url = api_url + '/commits?' + \
@@ -234,8 +319,8 @@ def get_packages(self):
try:
commit_info = json.loads(commit_json)
except (ValueError):
- sublime.error_message(__name__ + ': Error parsing JSON from ' +
- ' repository ' + commit_api_url + '.')
+ sublime.error_message(('%s: Error parsing JSON from ' +
+ 'repository %s.') % (__name__, commit_api_url))
return False
download_url = 'https://nodeload.github.com/' + \
@@ -254,7 +339,8 @@ def get_packages(self):
package = {
'name': repo_info['name'],
- 'description': repo_info['description'],
+ 'description': repo_info['description'] if \
+ repo_info['description'] else 'No description provided',
'url': homepage,
'author': repo_info['owner']['login'],
'last_modified': timestamp.strftime('%Y-%m-%d %H:%M:%S'),
@@ -294,8 +380,8 @@ def get_packages(self):
try:
repo_info = json.loads(repo_json)
except (ValueError):
- sublime.error_message(__name__ + ': Error parsing JSON from ' +
- ' repository ' + api_url + '.')
+ sublime.error_message(('%s: Error parsing JSON from ' +
+ 'repository %s.') % (__name__, api_url))
return False
packages = {}
@@ -311,8 +397,8 @@ def get_packages(self):
try:
commit_info = json.loads(commit_json)
except (ValueError):
- sublime.error_message(__name__ + ': Error parsing JSON from ' +
- ' repository ' + commit_api_url + '.')
+ sublime.error_message(('%s: Error parsing JSON from ' +
+ 'repository %s.') % (__name__, commit_api_url))
return False
commit_date = commit_info[0]['commit']['committer']['date']
@@ -327,7 +413,8 @@ def get_packages(self):
package = {
'name': package_info['name'],
- 'description': package_info['description'],
+ 'description': repo_info['description'] if \
+ repo_info['description'] else 'No description provided',
'url': homepage,
'author': package_info['owner']['login'],
'last_modified': timestamp.strftime('%Y-%m-%d %H:%M:%S'),
@@ -367,8 +454,8 @@ def get_packages(self):
try:
repo_info = json.loads(repo_json)
except (ValueError):
- sublime.error_message(__name__ + ': Error parsing JSON from ' +
- ' repository ' + api_url + '.')
+ sublime.error_message(('%s: Error parsing JSON from ' +
+ 'repository %s.') % (__name__, api_url))
return False
changeset_url = api_url + '/changesets/default'
@@ -379,8 +466,8 @@ def get_packages(self):
try:
last_commit = json.loads(changeset_json)
except (ValueError):
- sublime.error_message(__name__ + ': Error parsing JSON from ' +
- ' repository ' + changeset_url + '.')
+ sublime.error_message(('%s: Error parsing JSON from ' +
+ 'repository %s.') % (__name__, changeset_url))
return False
commit_date = last_commit['timestamp']
timestamp = datetime.datetime.strptime(commit_date[0:19],
@@ -392,8 +479,9 @@ def get_packages(self):
if not homepage:
homepage = self.repo
package = {
- 'name': repo_info['slug'],
- 'description': repo_info['description'],
+ 'name': repo_info['name'],
+ 'description': repo_info['description'] if \
+ repo_info['description'] else 'No description provided',
'url': homepage,
'author': repo_info['owner'],
'last_modified': timestamp.strftime('%Y-%m-%d %H:%M:%S'),
@@ -427,20 +515,42 @@ def __str__(self):
return repr(self.returncode)
-class CliDownloader():
+class Downloader():
+ def check_certs(self, domain, timeout):
+ cert_info = self.settings.get('certs', {}).get(
+ domain)
+ if not cert_info:
+ print '%s: No CA certs available for %s.' % (__name__,
+ domain)
+ return False
+ cert_path = os.path.join(sublime.packages_path(), 'Package Control',
+ 'certs', cert_info[0])
+ ca_bundle_path = os.path.join(sublime.packages_path(),
+ 'Package Control', 'certs', 'ca-bundle.crt')
+ if not os.path.exists(cert_path):
+ cert_downloader = self.__class__(self.settings)
+ cert_contents = cert_downloader.download(cert_info[1],
+ 'Error downloading CA certs for %s.' % (domain), timeout, 1)
+ if not cert_contents:
+ return False
+ with open(cert_path, 'wb') as f:
+ f.write(cert_contents)
+ with open(ca_bundle_path, 'ab') as f:
+ f.write("\n" + cert_contents)
+ return ca_bundle_path
+
+
+class CliDownloader(Downloader):
def __init__(self, settings):
self.settings = settings
def find_binary(self, name):
- dirs = ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin',
- '/sbin', '/bin']
- for dir in dirs:
+ for dir in os.environ['PATH'].split(os.pathsep):
path = os.path.join(dir, name)
if os.path.exists(path):
return path
- raise BinaryNotFoundError('The binary ' + name + ' could not be ' +
- 'located')
+ raise BinaryNotFoundError('The binary %s could not be located' % name)
def execute(self, args):
proc = subprocess.Popen(args, stdin=subprocess.PIPE,
@@ -455,7 +565,7 @@ def execute(self, args):
return output
-class UrlLib2Downloader():
+class UrlLib2Downloader(Downloader):
def __init__(self, settings):
self.settings = settings
@@ -473,7 +583,16 @@ def download(self, url, error_message, timeout, tries):
proxy_handler = urllib2.ProxyHandler(proxies)
else:
proxy_handler = urllib2.ProxyHandler()
- urllib2.install_opener(urllib2.build_opener(proxy_handler))
+ handlers = [proxy_handler]
+
+ secure_url_match = re.match('^https://([^/]+)', url)
+ if secure_url_match != None:
+ secure_domain = secure_url_match.group(1)
+ bundle_path = self.check_certs(secure_domain, timeout)
+ if not bundle_path:
+ return False
+ handlers.append(VerifiedHTTPSHandler(ca_certs=bundle_path))
+ urllib2.install_opener(urllib2.build_opener(*handlers))
while tries > 0:
tries -= 1
@@ -486,17 +605,18 @@ def download(self, url, error_message, timeout, tries):
except (urllib2.HTTPError) as (e):
# Bitbucket and Github ratelimit using 503 a decent amount
if str(e.code) == '503':
- print (__name__ + ': Downloading %s was rate limited, ' +
- 'trying again') % url
+ print ('%s: Downloading %s was rate limited, ' +
+ 'trying again') % (__name__, url)
continue
print '%s: %s HTTP error %s downloading %s.' % (__name__,
error_message, str(e.code), url)
+
except (urllib2.URLError) as (e):
# Bitbucket and Github timeout a decent amount
if str(e.reason) == 'The read operation timed out' or \
str(e.reason) == 'timed out':
- print (__name__ + ': Downloading %s timed out, trying ' +
- 'again') % url
+ print ('%s: Downloading %s timed out, trying ' +
+ 'again') % (__name__, url)
continue
print '%s: %s URL error %s downloading %s.' % (__name__,
error_message, str(e.reason), url)
@@ -518,7 +638,17 @@ def download(self, url, error_message, timeout, tries):
self.tmp_file = tempfile.NamedTemporaryFile().name
command = [self.wget, '--connect-timeout=' + str(int(timeout)), '-o',
- self.tmp_file, '-O', '-', '-U', 'Sublime Package Control', url]
+ self.tmp_file, '-O', '-', '-U', 'Sublime Package Control']
+
+ secure_url_match = re.match('^https://([^/]+)', url)
+ if secure_url_match != None:
+ secure_domain = secure_url_match.group(1)
+ bundle_path = self.check_certs(secure_domain, timeout)
+ if not bundle_path:
+ return False
+ command.append(u'--ca-certificate=' + bundle_path)
+
+ command.append(url)
if self.settings.get('http_proxy'):
os.putenv('http_proxy', self.settings.get('http_proxy'))
@@ -527,7 +657,7 @@ def download(self, url, error_message, timeout, tries):
if self.settings.get('https_proxy'):
os.putenv('https_proxy', self.settings.get('https_proxy'))
- while tries > 1:
+ while tries > 0:
tries -= 1
try:
result = self.execute(command)
@@ -545,8 +675,8 @@ def download(self, url, error_message, timeout, tries):
regex = re.compile('^.*ERROR (\d+):.*', re.S)
if re.sub(regex, '\\1', error_line) == '503':
# GitHub and BitBucket seem to rate limit via 503
- print (__name__ + ': Downloading %s was rate limited' +
- ', trying again') % url
+ print ('%s: Downloading %s was rate limited' +
+ ', trying again') % (__name__, url)
continue
error_string = 'HTTP error ' + re.sub('^.*? ERROR ', '',
error_line)
@@ -555,8 +685,8 @@ def download(self, url, error_message, timeout, tries):
error_string = re.sub('^.*?failed: ', '', error_line)
# GitHub and BitBucket seem to time out a lot
if error_string.find('timed out') != -1:
- print (__name__ + ': Downloading %s timed out, ' +
- 'trying again') % url
+ print ('%s: Downloading %s timed out, ' +
+ 'trying again') % (__name__, url)
continue
else:
@@ -580,7 +710,17 @@ def download(self, url, error_message, timeout, tries):
if not self.curl:
return False
command = [self.curl, '-f', '--user-agent', 'Sublime Package Control',
- '--connect-timeout', str(int(timeout)), '-sS', url]
+ '--connect-timeout', str(int(timeout)), '-sS']
+
+ secure_url_match = re.match('^https://([^/]+)', url)
+ if secure_url_match != None:
+ secure_domain = secure_url_match.group(1)
+ bundle_path = self.check_certs(secure_domain, timeout)
+ if not bundle_path:
+ return False
+ command.extend(['--cacert', bundle_path])
+
+ command.append(url)
if self.settings.get('http_proxy'):
os.putenv('http_proxy', self.settings.get('http_proxy'))
@@ -589,7 +729,7 @@ def download(self, url, error_message, timeout, tries):
if self.settings.get('https_proxy'):
os.putenv('HTTPS_PROXY', self.settings.get('https_proxy'))
- while tries > 1:
+ while tries > 0:
tries -= 1
try:
return self.execute(command)
@@ -598,19 +738,19 @@ def download(self, url, error_message, timeout, tries):
code = re.sub('^.*?(\d+)\s*$', '\\1', e.output)
if code == '503':
# GitHub and BitBucket seem to rate limit via 503
- print (__name__ + ': Downloading %s was rate limited' +
- ', trying again') % url
+ print ('%s: Downloading %s was rate limited' +
+ ', trying again') % (__name__, url)
continue
error_string = 'HTTP error ' + code
elif e.returncode == 6:
error_string = 'URL error host not found'
elif e.returncode == 28:
# GitHub and BitBucket seem to time out a lot
- print (__name__ + ': Downloading %s timed out, trying ' +
- 'again') % url
+ print ('%s: Downloading %s timed out, trying ' +
+ 'again') % (__name__, url)
continue
else:
- error_string = e.output
+ error_string = e.output.rstrip()
print '%s: %s %s downloading %s.' % (__name__, error_message,
error_string, url)
@@ -673,6 +813,15 @@ def find_binary(self, name):
if self.binary:
return self.binary
+ # Try the path first
+ for dir in os.environ['PATH'].split(os.pathsep):
+ path = os.path.join(dir, name)
+ if os.path.exists(path):
+ return path
+
+ # This is left in for backwards compatibility and for windows
+ # users who may have the binary, albeit in a common dir that may
+ # not be part of the PATH
if os.name == 'nt':
dirs = ['C:\\Program Files\\Git\\bin',
'C:\\Program Files (x86)\\Git\\bin',
@@ -683,9 +832,7 @@ def find_binary(self, name):
'C:\\Program Files\\TortoiseHg',
'C:\\cygwin\\bin']
else:
- dirs = ['/usr/local/git/bin', '/usr/local/sbin',
- '/usr/local/bin', '/usr/sbin',
- '/usr/bin', '/sbin', '/bin']
+ dirs = ['/usr/local/git/bin']
for dir in dirs:
path = os.path.join(dir, name)
@@ -816,7 +963,9 @@ def __init__(self):
'git_binary', 'git_update_command', 'hg_binary',
'hg_update_command', 'http_proxy', 'https_proxy',
'auto_upgrade_ignore', 'auto_upgrade_frequency',
- 'submit_usage', 'submit_url', 'renamed_packages']:
+ 'submit_usage', 'submit_url', 'renamed_packages',
+ 'files_to_include', 'files_to_include_binary', 'certs',
+ 'ignore_vcs_packages']:
if settings.get(setting) == None:
continue
self.settings[setting] = settings.get(setting)
@@ -834,7 +983,7 @@ def normalize(v):
return cmp(normalize(version1), normalize(version2))
def download_url(self, url, error_message):
- has_ssl = 'ssl' in sys.modules
+ has_ssl = 'ssl' in sys.modules and hasattr(urllib2, 'HTTPSHandler')
is_ssl = re.search('^https://', url) != None
if (is_ssl and has_ssl) or not is_ssl:
@@ -848,9 +997,9 @@ def download_url(self, url, error_message):
pass
if not downloader:
- sublime.error_message(__name__ + ': Unable to download ' +
- url + ' due to no ssl module available and no capable ' +
- 'program found. Please install curl or wget.')
+ sublime.error_message(('%s: Unable to download %s due to no ' +
+ 'ssl module available and no capable program found. Please ' +
+ 'install curl or wget.') % (__name__, url))
return False
timeout = self.settings.get('timeout', 3)
@@ -899,6 +1048,13 @@ def list_repositories(self):
{}))
self.settings['renamed_packages'] = renamed_packages
+ certs_cache_key = channel + '.certs'
+ certs_cache = _channel_repository_cache.get(certs_cache_key)
+ if certs_cache and certs_cache.get('time') > time.time():
+ certs = self.settings.get('certs', {})
+ certs.update(certs_cache.get('data'))
+ self.settings['certs'] = certs
+
if channel_repositories == None or \
self.settings.get('package_name_map') == None or \
self.settings.get('renamed_packages') == None:
@@ -948,6 +1104,16 @@ def list_repositories(self):
'renamed_packages', {})
self.settings['renamed_packages'].update(renamed_packages)
+ certs = provider.get_certs()
+ _channel_repository_cache[certs_cache_key] = {
+ 'time': time.time() + self.settings.get('cache_length',
+ 300),
+ 'data': certs
+ }
+ if certs:
+ self.settings['certs'] = self.settings.get('certs', {})
+ self.settings['certs'].update(certs)
+
repositories.extend(channel_repositories)
return repositories
@@ -1069,9 +1235,9 @@ def create_package(self, package_name, package_destination,
package_dir = self.get_package_dir(package_name) + '/'
if not os.path.exists(package_dir):
- sublime.error_message(__name__ + ': The folder for the ' +
- 'package name specified, %s, does not exist in %s' %
- (package_name, sublime.packages_path()))
+ sublime.error_message(('%s: The folder for the package name ' +
+ 'specified, %s, does not exist in %s') %
+ (__name__, package_name, sublime.packages_path()))
return False
package_filename = package_name + '.sublime-package'
@@ -1088,16 +1254,18 @@ def create_package(self, package_name, package_destination,
package_file = zipfile.ZipFile(package_path, "w",
compression=zipfile.ZIP_DEFLATED)
except (OSError, IOError) as (exception):
- sublime.error_message(__name__ + ': An error occurred ' +
- 'creating the package file %s in %s. %s' % (package_filename,
+ sublime.error_message(('%s: An error occurred creating the ' +
+ 'package file %s in %s. %s') % (__name__, package_filename,
package_destination, str(exception)))
return False
dirs_to_ignore = self.settings.get('dirs_to_ignore', [])
if not binary_package:
files_to_ignore = self.settings.get('files_to_ignore', [])
+ files_to_include = self.settings.get('files_to_include', [])
else:
files_to_ignore = self.settings.get('files_to_ignore_binary', [])
+ files_to_include = self.settings.get('files_to_include_binary', [])
package_dir_regex = re.compile('^' + re.escape(package_dir))
for root, dirs, files in os.walk(package_dir):
@@ -1105,19 +1273,18 @@ def create_package(self, package_name, package_destination,
paths = dirs
paths.extend(files)
for path in paths:
- if any(fnmatch.fnmatch(path, pattern) for pattern in
- files_to_ignore):
- continue
full_path = os.path.join(root, path)
relative_path = re.sub(package_dir_regex, '', full_path)
+
+ ignore_matches = [fnmatch(relative_path, p) for p in files_to_ignore]
+ include_matches = [fnmatch(relative_path, p) for p in files_to_include]
+ if any(ignore_matches) and not any(include_matches):
+ continue
+
if os.path.isdir(full_path):
continue
package_file.write(full_path, relative_path)
- init_script = os.path.join(package_dir, '__init__.py')
- if binary_package and os.path.exists(init_script):
- package_file.write(init_script, re.sub(package_dir_regex, '',
- init_script))
package_file.close()
return True
@@ -1126,8 +1293,8 @@ def install_package(self, package_name):
packages = self.list_available_packages()
if package_name not in packages.keys():
- sublime.error_message(__name__ + ': The package specified,' +
- ' %s, is not available.' % (package_name,))
+ sublime.error_message(('%s: The package specified, %s, is ' +
+ 'not available.') % (__name__, package_name))
return False
download = packages[package_name]['downloads'][0]
@@ -1146,10 +1313,20 @@ def install_package(self, package_name):
'package-metadata.json')
if os.path.exists(os.path.join(package_dir, '.git')):
+ if self.settings.get('ignore_vcs_packages'):
+ sublime.error_message(('%s: Skipping git package %s since ' +
+ 'the setting ignore_vcs_packages is set to true') %
+ (__name__, package_name))
+ return False
return GitUpgrader(self.settings['git_binary'],
self.settings['git_update_command'], package_dir,
self.settings['cache_length']).run()
elif os.path.exists(os.path.join(package_dir, '.hg')):
+ if self.settings.get('ignore_vcs_packages'):
+ sublime.error_message(('%s: Skipping hg package %s since ' +
+ 'the setting ignore_vcs_packages is set to true') %
+ (__name__, package_name))
+ return False
return HgUpgrader(self.settings['hg_binary'],
self.settings['hg_update_command'], package_dir,
self.settings['cache_length']).run()
@@ -1179,23 +1356,30 @@ def install_package(self, package_name):
package_backup_dir = os.path.join(backup_dir, package_name)
shutil.copytree(package_dir, package_backup_dir)
except (OSError, IOError) as (exception):
- sublime.error_message(__name__ + ': An error occurred while' +
- ' trying to backup the package directory for %s. %s' %
- (package_name, str(exception)))
+ sublime.error_message(('%s: An error occurred while trying ' +
+ 'to backup the package directory for %s. %s') %
+ (__name__, package_name, str(exception)))
shutil.rmtree(package_backup_dir)
return False
- package_zip = zipfile.ZipFile(package_path, 'r')
+ try:
+ package_zip = zipfile.ZipFile(package_path, 'r')
+ except (zipfile.BadZipfile):
+ sublime.error_message(('%s: An error occurred while ' +
+ 'trying to unzip the package file for %s. Please try ' +
+ 'installing the package again.') % (__name__, package_name))
+ return False
+
root_level_paths = []
last_path = None
for path in package_zip.namelist():
last_path = path
if path.find('/') in [len(path) - 1, -1]:
root_level_paths.append(path)
- if path[0] == '/' or path.find('..') != -1:
- sublime.error_message(__name__ + ': The package ' +
- 'specified, %s, contains files outside of the package ' +
- 'dir and cannot be safely installed.' % (package_name,))
+ if path[0] == '/' or path.find('../') != -1 or path.find('..\\') != -1:
+ sublime.error_message(('%s: The package specified, %s, ' +
+ 'contains files outside of the package dir and cannot ' +
+ 'be safely installed.') % (__name__, package_name))
return False
if last_path and len(root_level_paths) == 0:
@@ -1218,9 +1402,8 @@ def install_package(self, package_name):
if os.name == 'nt':
regex = ':|\*|\?|"|<|>|\|'
if re.search(regex, dest) != None:
- print ('%s: Skipping file from package ' +
- 'named %s due to an invalid filename') % (__name__,
- path)
+ print ('%s: Skipping file from package named %s due to ' +
+ 'an invalid filename') % (__name__, path)
continue
# If there was only a single directory in the package, we remove
@@ -1255,9 +1438,8 @@ def add_extracted_dirs(dir):
try:
open(dest, 'wb').write(package_zip.read(path))
except (IOError, UnicodeDecodeError):
- print ('%s: Skipping file from package ' +
- 'named %s due to an invalid filename') % (__name__,
- path)
+ print ('%s: Skipping file from package named %s due to ' +
+ 'an invalid filename') % (__name__, path)
package_zip.close()
# Here we clean out any files that were not just overwritten
@@ -1405,8 +1587,8 @@ def remove_package(self, package_name):
installed_packages = self.list_packages()
if package_name not in installed_packages:
- sublime.error_message(__name__ + ': The package specified,' +
- ' %s, is not installed.' % (package_name,))
+ sublime.error_message(('%s: The package specified, %s, is not ' +
+ 'installed.') % (__name__, package_name))
return False
os.chdir(sublime.packages_path())
@@ -1429,27 +1611,27 @@ def remove_package(self, package_name):
if os.path.exists(package_path):
os.remove(package_path)
except (OSError, IOError) as (exception):
- sublime.error_message(__name__ + ': An error occurred while' +
- ' trying to remove the package file for %s. %s' %
- (package_name, str(exception)))
+ sublime.error_message(('%s: An error occurred while trying to ' +
+ 'remove the package file for %s. %s') % (__name__,
+ package_name, str(exception)))
return False
try:
if os.path.exists(installed_package_path):
os.remove(installed_package_path)
except (OSError, IOError) as (exception):
- sublime.error_message(__name__ + ': An error occurred while' +
- ' trying to remove the installed package file for %s. %s' %
- (package_name, str(exception)))
+ sublime.error_message(('%s: An error occurred while trying to ' +
+ 'remove the installed package file for %s. %s') % (__name__,
+ package_name, str(exception)))
return False
try:
if os.path.exists(pristine_package_path):
os.remove(pristine_package_path)
except (OSError, IOError) as (exception):
- sublime.error_message(__name__ + ': An error occurred while' +
- ' trying to remove the pristine package file for %s. %s' %
- (package_name, str(exception)))
+ sublime.error_message(('%s: An error occurred while trying to ' +
+ 'remove the pristine package file for %s. %s') % (__name__,
+ package_name, str(exception)))
return False
# We don't delete the actual package dir immediately due to a bug
@@ -1478,13 +1660,13 @@ def remove_package(self, package_name):
# Remove the package from the installed packages list
def clear_package():
- settings = sublime.load_settings(__name__ + '.sublime-settings')
+ settings = sublime.load_settings('%s.sublime-settings' % __name__)
installed_packages = settings.get('installed_packages', [])
if not installed_packages:
installed_packages = []
installed_packages.remove(package_name)
settings.set('installed_packages', installed_packages)
- sublime.save_settings(__name__ + '.sublime-settings')
+ sublime.save_settings('%s.sublime-settings' % __name__)
sublime.set_timeout(clear_package, 1)
if can_delete_dir:
@@ -1500,14 +1682,18 @@ def record_usage(self, params):
params['sublime_platform'] = self.settings.get('platform')
params['sublime_version'] = self.settings.get('version')
url = self.settings.get('submit_url') + '?' + urllib.urlencode(params)
+
result = self.download_url(url, 'Error submitting usage information.')
+ if result == False:
+ return
+
try:
result = json.loads(result)
if result['result'] != 'success':
raise ValueError()
except (ValueError):
- print '%s: Error submitting usage information for %s' % \
- (__name__, params['package'])
+ print '%s: Error submitting usage information for %s' % (__name__,
+ params['package'])
class PackageCreator():
@@ -1515,8 +1701,8 @@ def show_panel(self):
self.manager = PackageManager()
self.packages = self.manager.list_packages()
if not self.packages:
- sublime.error_message(__name__ + ': There are no packages ' +
- 'available to be packaged.')
+ sublime.error_message(('%s: There are no packages available to ' +
+ 'be packaged.') % (__name__))
return
self.window.show_quick_panel(self.packages, self.on_done)
@@ -1526,8 +1712,7 @@ def get_package_destination(self):
# We check destination via an if statement instead of using
# the dict.get() method since the key may be set, but to a blank value
if not destination:
- destination = os.path.join(os.path.expanduser('~'),
- 'Desktop')
+ destination = os.path.join(os.path.expanduser('~'), 'Desktop')
return destination
@@ -1607,12 +1792,16 @@ def make_package_list(self, ignore_actions=[], override_action=None,
else:
if os.path.exists(os.path.join(sublime.packages_path(),
package, '.git')):
+ if settings.get('ignore_vcs_packages'):
+ continue
vcs = 'git'
incoming = GitUpgrader(settings.get('git_binary'),
settings.get('git_update_command'), package_dir,
settings.get('cache_length')).incoming()
elif os.path.exists(os.path.join(sublime.packages_path(),
package, '.hg')):
+ if settings.get('ignore_vcs_packages'):
+ continue
vcs = 'hg'
incoming = HgUpgrader(settings.get('hg_binary'),
settings.get('hg_update_command'), package_dir,
@@ -1653,8 +1842,10 @@ def make_package_list(self, ignore_actions=[], override_action=None,
if action in ignore_actions:
continue
- package_entry.append(info.get('description', 'No description ' +
- 'provided'))
+ description = info.get('description')
+ if not description:
+ description = 'No description provided'
+ package_entry.append(description)
package_entry.append(action + extra + ' ' +
re.sub('^https?://', '', info['url']))
package_list.append(package_entry)
@@ -1700,8 +1891,8 @@ def run(self):
def show_quick_panel():
if not self.package_list:
- sublime.error_message(__name__ + ': There are no packages ' +
- 'available for installation.')
+ sublime.error_message(('%s: There are no packages ' +
+ 'available for installation.') % __name__)
return
self.window.show_quick_panel(self.package_list, self.on_done)
sublime.set_timeout(show_quick_panel, 10)
@@ -1733,8 +1924,8 @@ def run(self):
def show_quick_panel():
if not self.package_list:
- sublime.error_message(__name__ + ': There are no packages ' +
- 'ready for upgrade.')
+ sublime.error_message(('%s: There are no packages ' +
+ 'ready for upgrade.') % __name__)
return
self.window.show_quick_panel(self.package_list, self.on_done)
sublime.set_timeout(show_quick_panel, 10)
@@ -1787,8 +1978,10 @@ def make_package_list(self, action=''):
metadata = self.manager.get_metadata(package)
package_dir = os.path.join(sublime.packages_path(), package)
- package_entry.append(metadata.get('description',
- 'No description provided'))
+ description = metadata.get('description')
+ if not description:
+ description = 'No description provided'
+ package_entry.append(description)
version = metadata.get('version')
if not version and os.path.exists(os.path.join(package_dir,
@@ -1829,8 +2022,8 @@ def run(self):
def show_quick_panel():
if not self.package_list:
- sublime.error_message(__name__ + ': There are no packages ' +
- 'to list.')
+ sublime.error_message(('%s: There are no packages ' +
+ 'to list.') % __name__)
return
self.window.show_quick_panel(self.package_list, self.on_done)
sublime.set_timeout(show_quick_panel, 10)
@@ -1855,8 +2048,8 @@ def __init__(self, window):
def run(self):
self.package_list = self.make_package_list('remove')
if not self.package_list:
- sublime.error_message(__name__ + ': There are no packages ' +
- 'that can be removed.')
+ sublime.error_message(('%s: There are no packages ' +
+ 'that can be removed.') % __name__)
return
self.window.show_quick_panel(self.package_list, self.on_done)
@@ -1900,19 +2093,19 @@ def unignore_package():
class AddRepositoryChannelCommand(sublime_plugin.WindowCommand):
def run(self):
- self.window.show_input_panel('Repository Channel JSON URL', '',
+ self.window.show_input_panel('Channel JSON URL', '',
self.on_done, self.on_change, self.on_cancel)
def on_done(self, input):
- settings = sublime.load_settings(__name__ + '.sublime-settings')
+ settings = sublime.load_settings('%s.sublime-settings' % __name__)
repository_channels = settings.get('repository_channels', [])
if not repository_channels:
repository_channels = []
repository_channels.append(input)
settings.set('repository_channels', repository_channels)
- sublime.save_settings(__name__ + '.sublime-settings')
- sublime.status_message('Repository channel ' + input +
- ' successfully added')
+ sublime.save_settings('%s.sublime-settings' % __name__)
+ sublime.status_message(('Channel %s successfully ' +
+ 'added') % input)
def on_change(self, input):
pass
@@ -1928,14 +2121,14 @@ def run(self):
self.on_change, self.on_cancel)
def on_done(self, input):
- settings = sublime.load_settings(__name__ + '.sublime-settings')
+ settings = sublime.load_settings('%s.sublime-settings' % __name__)
repositories = settings.get('repositories', [])
if not repositories:
repositories = []
repositories.append(input)
settings.set('repositories', repositories)
- sublime.save_settings(__name__ + '.sublime-settings')
- sublime.status_message('Repository ' + input + ' successfully added')
+ sublime.save_settings('%s.sublime-settings' % __name__)
+ sublime.status_message('Repository %s successfully added' % input)
def on_change(self, input):
pass
@@ -1955,8 +2148,8 @@ def run(self):
self.package_list = list(set(packages) - set(disabled_packages))
self.package_list.sort()
if not self.package_list:
- sublime.error_message(__name__ + ': There are no enabled ' +
- 'packages to disable.')
+ sublime.error_message(('%s: There are no enabled packages' +
+ 'to disable.') % __name__)
return
self.window.show_quick_panel(self.package_list, self.on_done)
@@ -1970,9 +2163,9 @@ def on_done(self, picked):
ignored_packages.append(package)
self.settings.set('ignored_packages', ignored_packages)
sublime.save_settings('Global.sublime-settings')
- sublime.status_message('Package ' + package + ' successfully added ' +
- 'to list of disabled packages - restarting Sublime Text may be '
- 'required')
+ sublime.status_message(('Package %s successfully added to list of ' +
+ 'disabled packages - restarting Sublime Text may be required') %
+ package)
class EnablePackageCommand(sublime_plugin.WindowCommand):
@@ -1981,8 +2174,8 @@ def run(self):
self.disabled_packages = self.settings.get('ignored_packages')
self.disabled_packages.sort()
if not self.disabled_packages:
- sublime.error_message(__name__ + ': There are no disabled ' +
- 'packages to enable.')
+ sublime.error_message(('%s: There are no disabled packages ' +
+ 'to enable.') % __name__)
return
self.window.show_quick_panel(self.disabled_packages, self.on_done)
@@ -1994,9 +2187,9 @@ def on_done(self, picked):
self.settings.set('ignored_packages',
list(set(ignored) - set([package])))
sublime.save_settings('Global.sublime-settings')
- sublime.status_message('Package ' + package + ' successfully removed' +
- ' from list of disabled packages - restarting Sublime Text may be '
- 'required')
+ sublime.status_message(('Package %s successfully removed from list ' +
+ 'of disabled packages - restarting Sublime Text may be required') %
+ package)
class PackageStartup():
@@ -2159,11 +2352,18 @@ def run(self):
metadata_path = os.path.join(package_dir, 'package-metadata.json')
# Cleanup packages that could not be removed due to in-use files
- if os.path.exists(os.path.join(package_dir,
- 'package-control.cleanup')):
- shutil.rmtree(package_dir)
- print '%s: Removed old directory for package %s' % \
- (__name__, package_name)
+ cleanup_file = os.path.join(package_dir, 'package-control.cleanup')
+ if os.path.exists(cleanup_file):
+ try:
+ shutil.rmtree(package_dir)
+ print '%s: Removed old directory for package %s' % \
+ (__name__, package_name)
+ except (OSError) as (e):
+ if not os.path.exists(cleanup_file):
+ open(cleanup_file, 'w').close()
+ print ('%s: Unable to remove old directory for package ' +
+ '%s - deferring until next start: %s') % (__name__,
+ package_name, str(e))
# This adds previously installed packages from old versions of PC
if os.path.exists(metadata_path) and \
diff --git a/Package Control/Package Control.pyc b/Package Control/Package Control.pyc
deleted file mode 100644
index 6173636..0000000
Binary files a/Package Control/Package Control.pyc and /dev/null differ
diff --git a/Package Control/Package Control.sublime-settings b/Package Control/Package Control.sublime-settings
index 2ab981c..b2b03b5 100644
--- a/Package Control/Package Control.sublime-settings
+++ b/Package Control/Package Control.sublime-settings
@@ -3,7 +3,7 @@
// The repositories from these channels are placed in order after the
// repositories from the "repositories" setting
"repository_channels": [
- "http://sublime.wbond.net/repositories.json"
+ "https://sublime.wbond.net/repositories.json"
],
// A list of URLs that contain a packages JSON file. These repositories
@@ -11,6 +11,10 @@
// setting
"repositories": [],
+ "certs": {
+ "sublime.wbond.net": ["7f4f8622b4fd001c7f648e09aae7edaa", ""]
+ },
+
// This helps solve naming issues where a repository it not named the
// same as the package should be. This is primarily only useful for
// GitHub and BitBucket repositories. This mapping will override the
@@ -22,7 +26,7 @@
"submit_usage": true,
// The URL to post install, upgrade and removal notices to
- "submit_url": "http://sublime.wbond.net/submit",
+ "submit_url": "https://sublime.wbond.net/submit",
// If packages should be automatically upgraded when ST2 starts
"auto_upgrade": true,
@@ -46,12 +50,18 @@
// http_proxy is, http_proxy will be used for https_proxy also
"https_proxy": "",
+ // Setting this to true will cause Package Control to ignore all git
+ // and hg repositories - this may help if trying to list packages to install
+ // hangs
+ "ignore_vcs_packages": false,
+
// Custom paths to VCS binaries for when they can't be automatically
// found on the system and a package includes a VCS metadata directory
"git_binary": "",
- "git_update_command": ["pull", "origin", "master"],
+ "git_update_command": ["pull", "origin", "master", "--ff", "--commit"],
"hg_binary": "",
+
// Be sure to keep the remote name as the last argument
"hg_update_command": ["pull", "--update", "default"],
@@ -59,11 +69,16 @@
"dirs_to_ignore": [
".hg", ".git", ".svn", "_darcs", "CVS"
],
+
// Files to ignore when creating a package
"files_to_ignore": [
".hgignore", ".gitignore", ".bzrignore", "*.pyc", "*.sublime-project",
"*.sublime-workspace", "*.tmTheme.cache"
],
+
+ // Files to include, even if they match a pattern in files_to_ignore
+ "files_to_include": [],
+
// Files to ignore when creating a binary package. By default binary
// packages ship with .pyc files instead of .py files. If an __init__.py
// file exists, it will always be included, even if it matches one of
@@ -72,6 +87,13 @@
".hgignore", ".gitignore", ".bzrignore", "*.py", "*.sublime-project",
"*.sublime-workspace", "*.tmTheme.cache"
],
+
+ // Files to include for a binary package, even if they match a pattern i
+ // files_to_ignore_binary
+ "files_to_include_binary": [
+ "__init__.py"
+ ],
+
// When a package is created, copy it to this folder - defaults to Desktop
"package_destination": ""
}
\ No newline at end of file
diff --git a/Package Control/package-metadata.json b/Package Control/package-metadata.json
index 913cf6f..c634a81 100644
--- a/Package Control/package-metadata.json
+++ b/Package Control/package-metadata.json
@@ -1 +1 @@
-{"url": "http://wbond.net/sublime_packages/package_control", "version": "1.4.1", "description": "A full-featured package manager"}
\ No newline at end of file
+{"url": "http://wbond.net/sublime_packages/package_control", "version": "1.5.0", "description": "A full-featured package manager"}
\ No newline at end of file
diff --git a/Perl/Miscellaneous.tmPreferences.cache b/Perl/Miscellaneous.tmPreferences.cache
deleted file mode 100644
index 49130fa..0000000
Binary files a/Perl/Miscellaneous.tmPreferences.cache and /dev/null differ
diff --git a/Perl/Perl.tmLanguage.cache b/Perl/Perl.tmLanguage.cache
deleted file mode 100644
index fbf392e..0000000
Binary files a/Perl/Perl.tmLanguage.cache and /dev/null differ
diff --git a/Python/Miscellaneous.tmPreferences.cache b/Python/Miscellaneous.tmPreferences.cache
deleted file mode 100644
index 541d0c0..0000000
Binary files a/Python/Miscellaneous.tmPreferences.cache and /dev/null differ
diff --git a/Python/Python.tmLanguage.cache b/Python/Python.tmLanguage.cache
deleted file mode 100644
index a031d89..0000000
Binary files a/Python/Python.tmLanguage.cache and /dev/null differ
diff --git a/Python/Regular Expressions (Python).tmLanguage.cache b/Python/Regular Expressions (Python).tmLanguage.cache
deleted file mode 100644
index d726e15..0000000
Binary files a/Python/Regular Expressions (Python).tmLanguage.cache and /dev/null differ
diff --git a/Python/Symbol List Hide Decorator.tmPreferences.cache b/Python/Symbol List Hide Decorator.tmPreferences.cache
deleted file mode 100644
index a7d95c1..0000000
Binary files a/Python/Symbol List Hide Decorator.tmPreferences.cache and /dev/null differ
diff --git a/Python/Symbol List.tmPreferences.cache b/Python/Symbol List.tmPreferences.cache
deleted file mode 100644
index 28f7a23..0000000
Binary files a/Python/Symbol List.tmPreferences.cache and /dev/null differ
diff --git a/R/Comments.tmPreferences.cache b/R/Comments.tmPreferences.cache
deleted file mode 100644
index 210f5e9..0000000
Binary files a/R/Comments.tmPreferences.cache and /dev/null differ
diff --git a/R/Methods.tmPreferences.cache b/R/Methods.tmPreferences.cache
deleted file mode 100644
index c2962d5..0000000
Binary files a/R/Methods.tmPreferences.cache and /dev/null differ
diff --git a/R/R Console.tmLanguage.cache b/R/R Console.tmLanguage.cache
deleted file mode 100644
index b615906..0000000
Binary files a/R/R Console.tmLanguage.cache and /dev/null differ
diff --git a/R/R.tmLanguage.cache b/R/R.tmLanguage.cache
deleted file mode 100644
index 5d780d4..0000000
Binary files a/R/R.tmLanguage.cache and /dev/null differ
diff --git a/R/Rd (R Documentation).tmLanguage.cache b/R/Rd (R Documentation).tmLanguage.cache
deleted file mode 100644
index 30ec45c..0000000
Binary files a/R/Rd (R Documentation).tmLanguage.cache and /dev/null differ
diff --git a/R/Symbol List (Rd Documentation).tmPreferences.cache b/R/Symbol List (Rd Documentation).tmPreferences.cache
deleted file mode 100644
index a869817..0000000
Binary files a/R/Symbol List (Rd Documentation).tmPreferences.cache and /dev/null differ
diff --git a/Rails/HTML (Rails).tmLanguage.cache b/Rails/HTML (Rails).tmLanguage.cache
deleted file mode 100644
index fa4f9ac..0000000
Binary files a/Rails/HTML (Rails).tmLanguage.cache and /dev/null differ
diff --git a/Rails/JavaScript (Rails).tmLanguage.cache b/Rails/JavaScript (Rails).tmLanguage.cache
deleted file mode 100644
index 18d5e56..0000000
Binary files a/Rails/JavaScript (Rails).tmLanguage.cache and /dev/null differ
diff --git a/Rails/Ruby Haml Comments.tmPreferences.cache b/Rails/Ruby Haml Comments.tmPreferences.cache
deleted file mode 100644
index c403ff3..0000000
Binary files a/Rails/Ruby Haml Comments.tmPreferences.cache and /dev/null differ
diff --git a/Rails/Ruby Haml.tmLanguage.cache b/Rails/Ruby Haml.tmLanguage.cache
deleted file mode 100644
index a6b3c6b..0000000
Binary files a/Rails/Ruby Haml.tmLanguage.cache and /dev/null differ
diff --git a/Rails/Ruby on Rails.tmLanguage.cache b/Rails/Ruby on Rails.tmLanguage.cache
deleted file mode 100644
index 3503a00..0000000
Binary files a/Rails/Ruby on Rails.tmLanguage.cache and /dev/null differ
diff --git a/Rails/SQL (Rails).tmLanguage.cache b/Rails/SQL (Rails).tmLanguage.cache
deleted file mode 100644
index 7f0875b..0000000
Binary files a/Rails/SQL (Rails).tmLanguage.cache and /dev/null differ
diff --git a/Rails/Template (ERB).tmPreferences.cache b/Rails/Template (ERB).tmPreferences.cache
deleted file mode 100644
index c42b69b..0000000
Binary files a/Rails/Template (ERB).tmPreferences.cache and /dev/null differ
diff --git a/Rails/Template (Haml).tmPreferences.cache b/Rails/Template (Haml).tmPreferences.cache
deleted file mode 100644
index d4b9c25..0000000
Binary files a/Rails/Template (Haml).tmPreferences.cache and /dev/null differ
diff --git a/Regular Expressions/RegExp.tmLanguage.cache b/Regular Expressions/RegExp.tmLanguage.cache
deleted file mode 100644
index db4c219..0000000
Binary files a/Regular Expressions/RegExp.tmLanguage.cache and /dev/null differ
diff --git a/RestructuredText/Comments.tmPreferences.cache b/RestructuredText/Comments.tmPreferences.cache
deleted file mode 100644
index fa0237d..0000000
Binary files a/RestructuredText/Comments.tmPreferences.cache and /dev/null differ
diff --git a/RestructuredText/reStructuredText.tmLanguage.cache b/RestructuredText/reStructuredText.tmLanguage.cache
deleted file mode 100644
index 098776d..0000000
Binary files a/RestructuredText/reStructuredText.tmLanguage.cache and /dev/null differ
diff --git a/Ruby/Comments.tmPreferences.cache b/Ruby/Comments.tmPreferences.cache
deleted file mode 100644
index 56e48ee..0000000
Binary files a/Ruby/Comments.tmPreferences.cache and /dev/null differ
diff --git a/Ruby/Miscellaneous.tmPreferences.cache b/Ruby/Miscellaneous.tmPreferences.cache
deleted file mode 100644
index 8f62265..0000000
Binary files a/Ruby/Miscellaneous.tmPreferences.cache and /dev/null differ
diff --git a/Ruby/Ruby.tmLanguage.cache b/Ruby/Ruby.tmLanguage.cache
deleted file mode 100644
index f085572..0000000
Binary files a/Ruby/Ruby.tmLanguage.cache and /dev/null differ
diff --git a/Ruby/Symbo List%3A Method.tmPreferences.cache b/Ruby/Symbo List%3A Method.tmPreferences.cache
deleted file mode 100644
index 7dd28d0..0000000
Binary files a/Ruby/Symbo List%3A Method.tmPreferences.cache and /dev/null differ
diff --git a/Ruby/Symbol List%3A No Function Call.tmPreferences.cache b/Ruby/Symbol List%3A No Function Call.tmPreferences.cache
deleted file mode 100644
index 21f23d4..0000000
Binary files a/Ruby/Symbol List%3A No Function Call.tmPreferences.cache and /dev/null differ
diff --git a/SQL/Comments.tmPreferences.cache b/SQL/Comments.tmPreferences.cache
deleted file mode 100644
index 0ab57c2..0000000
Binary files a/SQL/Comments.tmPreferences.cache and /dev/null differ
diff --git a/SQL/Miscellaneous.tmPreferences.cache b/SQL/Miscellaneous.tmPreferences.cache
deleted file mode 100644
index ebbd08d..0000000
Binary files a/SQL/Miscellaneous.tmPreferences.cache and /dev/null differ
diff --git a/SQL/SQL.tmLanguage.cache b/SQL/SQL.tmLanguage.cache
deleted file mode 100644
index 08e2bda..0000000
Binary files a/SQL/SQL.tmLanguage.cache and /dev/null differ
diff --git a/Scala/Comments.tmPreferences.cache b/Scala/Comments.tmPreferences.cache
deleted file mode 100644
index 60c16d5..0000000
Binary files a/Scala/Comments.tmPreferences.cache and /dev/null differ
diff --git a/Scala/Scala.tmLanguage.cache b/Scala/Scala.tmLanguage.cache
deleted file mode 100644
index a81bc4e..0000000
Binary files a/Scala/Scala.tmLanguage.cache and /dev/null differ
diff --git a/Scala/Symbols.tmPreferences.cache b/Scala/Symbols.tmPreferences.cache
deleted file mode 100644
index 361b069..0000000
Binary files a/Scala/Symbols.tmPreferences.cache and /dev/null differ
diff --git a/ShellScript/Comments.tmPreferences.cache b/ShellScript/Comments.tmPreferences.cache
deleted file mode 100644
index 3aa2083..0000000
Binary files a/ShellScript/Comments.tmPreferences.cache and /dev/null differ
diff --git a/ShellScript/Miscellaneous.tmPreferences.cache b/ShellScript/Miscellaneous.tmPreferences.cache
deleted file mode 100644
index 042d277..0000000
Binary files a/ShellScript/Miscellaneous.tmPreferences.cache and /dev/null differ
diff --git a/ShellScript/Shell-Unix-Generic.tmLanguage.cache b/ShellScript/Shell-Unix-Generic.tmLanguage.cache
deleted file mode 100644
index 5d7647e..0000000
Binary files a/ShellScript/Shell-Unix-Generic.tmLanguage.cache and /dev/null differ
diff --git a/TCL/Comments.tmPreferences.cache b/TCL/Comments.tmPreferences.cache
deleted file mode 100644
index 033b075..0000000
Binary files a/TCL/Comments.tmPreferences.cache and /dev/null differ
diff --git a/TCL/HTML (Tcl).tmLanguage.cache b/TCL/HTML (Tcl).tmLanguage.cache
deleted file mode 100644
index bdd29f8..0000000
Binary files a/TCL/HTML (Tcl).tmLanguage.cache and /dev/null differ
diff --git a/TCL/Tcl.tmLanguage.cache b/TCL/Tcl.tmLanguage.cache
deleted file mode 100644
index 6cde8ed..0000000
Binary files a/TCL/Tcl.tmLanguage.cache and /dev/null differ
diff --git a/Text/Plain text.tmLanguage.cache b/Text/Plain text.tmLanguage.cache
deleted file mode 100644
index 0375276..0000000
Binary files a/Text/Plain text.tmLanguage.cache and /dev/null differ
diff --git a/Textile/Textile.tmLanguage.cache b/Textile/Textile.tmLanguage.cache
deleted file mode 100644
index 52f4474..0000000
Binary files a/Textile/Textile.tmLanguage.cache and /dev/null differ
diff --git a/Theme - Default/Widgets.stTheme.cache b/Theme - Default/Widgets.stTheme.cache
deleted file mode 100644
index 63d1f4a..0000000
Binary files a/Theme - Default/Widgets.stTheme.cache and /dev/null differ
diff --git a/Theme - Soda/README.md b/Theme - Soda/README.md
index eba7775..1bd12dd 100644
--- a/Theme - Soda/README.md
+++ b/Theme - Soda/README.md
@@ -4,16 +4,20 @@ Dark and light custom UI themes for Sublime Text 2.
## Design
-
+
-
+
## Installation
-If you are a git user, the best way to install the theme and keep up to date is to clone the repo directly into your `Packages` directory in the Sublime Text 2 application settings area.
+### Using Sublime Package Control
+
+If you are using Will Bond's excellent [Sublime Package Control](http://wbond.net/sublime_packages/package_control), you can easily install Soda Theme via the `Package Control: Install Package` menu item. The Soda Theme package is listed as `Theme - Soda` in the packages list.
### Using Git
+Alternatively, if you are a git user, you can install the theme and keep up to date by cloning the repo directly into your `Packages` directory in the Sublime Text 2 application settings area.
+
Go to your Sublime Text 2 `Packages` directory and clone the theme repository using the command below:
git clone https://github.com/buymeasoda/soda-theme/ "Theme - Soda"
@@ -28,10 +32,10 @@ Go to your Sublime Text 2 `Packages` directory and clone the theme repository us
To configure Sublime Text 2 to use the theme:
-* Open your Sublime Text 2 User Global Preferences file `Sublime Text 2 -> Preferences -> Global Settings - User`
+* Open your User Settings Preferences file `Sublime Text 2 -> Preferences -> Settings - User`
* Add (or update) your theme entry to be `"theme": "Soda Light.sublime-theme"` or `"theme": "Soda Dark.sublime-theme"`
-### Example User Global Settings
+### Example User Settings
{
"theme": "Soda Light.sublime-theme"
diff --git a/Theme - Soda/Soda Dark.sublime-theme b/Theme - Soda/Soda Dark.sublime-theme
index e4d316f..3dfda26 100644
--- a/Theme - Soda/Soda Dark.sublime-theme
+++ b/Theme - Soda/Soda Dark.sublime-theme
@@ -47,13 +47,6 @@
"settings": ["show_tab_close_buttons"],
"content_margin": [22, 6, 15, 4]
},
- {
- // Tab dirty state
- "class": "tab_control",
- "settings": ["highlight_modified_tabs"],
- "attributes": ["dirty"],
- "content_margin": [22, 6, 15, 4]
- },
{
// Hover tab state
"class": "tab_control",
@@ -70,23 +63,21 @@
},
// Tab labels
{
- // Inactive tab label
"class": "tab_label",
"fade": true,
- "fg": [204, 204, 204],
- "bg": [66, 66, 66]
+ "fg": [175, 175, 175],
+ "shadow_color": [0, 0, 0],
+ "shadow_offset": [0, -1]
},
{
- // Inactive tab label hover
"class": "tab_label",
"parents": [{"class": "tab_control", "attributes": ["hover"]}],
- "bg": [75, 75, 75]
+ "fg": [200, 200, 200]
},
{
- // Active tab label
"class": "tab_label",
"parents": [{"class": "tab_control", "attributes": ["selected"]}],
- "bg": [78, 78, 78]
+ "fg": [245, 245, 245]
},
// Tab close button
{
@@ -107,7 +98,7 @@
"content_margin": [8, 8]
},
{
- // Tab close hover action
+ // Tab close button hover
"class": "tab_close_button",
"attributes": ["hover"],
"layer0.opacity": 0.0,
@@ -116,29 +107,33 @@
// Tab dirty button
{
"class": "tab_close_button",
- "settings": ["highlight_modified_tabs"],
"parents": [{"class": "tab_control", "attributes": ["dirty"]}],
- "content_margin": [8, 8],
"layer0.texture": "Theme - Soda/Soda Dark/tab-dirty.png",
- "layer0.opacity": 1.0,
+ "layer0.opacity": 1.0,
"layer1.opacity": 0.0
},
{
// Tab dirty button hover
"class": "tab_close_button",
- "settings": ["highlight_modified_tabs"],
"parents": [{"class": "tab_control", "attributes": ["dirty"]}],
"attributes": ["hover"],
"layer0.opacity": 0.0,
"layer1.opacity": 1.0
},
+ // Tab close button hidden with highlight modified flag true
+ {
+ // Tab dirty state (close button hidden)
+ "class": "tab_control",
+ "settings": ["!show_tab_close_buttons", "highlight_modified_tabs"],
+ "attributes": ["dirty"],
+ "content_margin": [22, 6, 15, 4]
+ },
{
- // Tab dirty button hover (close button hidden)
+ // Tab dirty button (close button hidden)
"class": "tab_close_button",
- "settings": ["highlight_modified_tabs"],
- "settings": ["!show_tab_close_buttons"],
+ "settings": ["!show_tab_close_buttons", "highlight_modified_tabs"],
"parents": [{"class": "tab_control", "attributes": ["dirty"]}],
- "attributes": ["hover"],
+ "content_margin": [8, 8],
"layer0.opacity": 1.0,
"layer1.opacity": 0.0
},
@@ -168,7 +163,7 @@
"attributes": ["pressed"],
"layer0.opacity": 0.0,
"layer1.opacity": 1.0
- },
+ },
{
"class": "fold_button_control",
"attributes": ["expanded"],
@@ -300,6 +295,16 @@
"layer0.opacity": 1.0
},
+//
+// GRID LAYOUT
+//
+
+ {
+ "class": "grid_layout_control",
+ "border_size": 1,
+ "border_color": [70, 70, 70]
+ },
+
//
// MINI MAP
//
@@ -422,17 +427,32 @@
"shadow_color": [0, 0, 0],
"shadow_offset": [0, 1]
},
- {
- "class": "sidebar_heading",
- "parents": [{"class": "tree_row", "attributes": ["selected"]}],
- "color": [210, 210, 210]
- },
// Sidebar entry
{
"class": "sidebar_label",
"color": [125, 125, 125],
"shadow_offset": [0, 0]
},
+ // Sidebar folder entry
+ {
+ "class": "sidebar_label",
+ "parents": [{"class": "tree_row", "attributes": ["expandable"]}],
+ "color": [210, 210, 210],
+ "shadow_color": [0, 0, 0],
+ "shadow_offset": [0, 1]
+ },
+ {
+ "class": "sidebar_label",
+ "parents": [{"class": "tree_row", "attributes": ["expandable", "hover"]}],
+ "color": [235, 235, 235]
+ },
+ {
+ "class": "sidebar_label",
+ "parents": [{"class": "tree_row", "attributes": ["expandable"]}],
+ "settings": ["bold_folder_labels"],
+ "font.bold": true
+ },
+ // Sidebar entry selected
{
"class": "sidebar_label",
"parents": [{"class": "tree_row", "attributes": ["selected"]}],
@@ -441,7 +461,7 @@
"shadow_offset": [0, 1]
},
// Sidebar file close
- {
+ {
"class": "close_button",
"layer0.texture": "Theme - Soda/Soda Dark/file-close.png",
"layer0.opacity": 0.0,
@@ -610,27 +630,27 @@
},
{
"class": "quick_panel_label",
- "fg": [190, 190, 190, 255],
- "match_fg": [255, 255, 255, 255],
+ "fg": [210, 210, 210, 255],
+ "match_fg": [126, 199, 239, 255],
"bg": [41, 41, 41, 255],
- "selected_fg": [200, 200, 200, 255],
- "selected_match_fg": [255, 255, 255, 255],
+ "selected_fg": [255, 255, 255, 255],
+ "selected_match_fg": [166, 229, 255, 255],
"selected_bg": [24, 24, 24, 255]
},
{
"class": "quick_panel_path_label",
- "fg": [120, 120, 120, 255],
- "match_fg": [200, 200, 200, 255],
+ "fg": [130, 130, 130, 255],
+ "match_fg": [220, 220, 220, 255],
"bg": [41, 41, 41, 255],
- "selected_fg": [130, 130, 130, 255],
- "selected_match_fg": [255, 255, 255, 255],
+ "selected_fg": [175, 175, 175, 255],
+ "selected_match_fg": [220, 220, 220, 255],
"selected_bg": [24, 24, 24, 255]
},
{
"class": "quick_panel_score_label",
- "fg": [137, 208, 244, 255],
+ "fg": [126, 199, 239, 255],
"bg": [41, 41, 41, 255],
- "selected_fg": [137, 208, 244, 255],
+ "selected_fg": [166, 229, 255, 255],
"selected_bg": [24, 24, 24, 255]
},
@@ -865,4 +885,4 @@
"layer0.texture": "Theme - Soda/Soda Dark/icon-highlight-on.png"
}
-]
\ No newline at end of file
+]
diff --git a/Theme - Soda/Soda Light.sublime-theme b/Theme - Soda/Soda Light.sublime-theme
index c7b6461..57ef803 100644
--- a/Theme - Soda/Soda Light.sublime-theme
+++ b/Theme - Soda/Soda Light.sublime-theme
@@ -46,13 +46,6 @@
"class": "tab_control",
"settings": ["show_tab_close_buttons"],
"content_margin": [22, 6, 15, 4]
- },
- {
- // Tab dirty state
- "class": "tab_control",
- "settings": ["highlight_modified_tabs"],
- "attributes": ["dirty"],
- "content_margin": [22, 6, 15, 4]
},
{
// Hover tab state
@@ -70,23 +63,22 @@
},
// Tab labels
{
- // Inactive tab label
"class": "tab_label",
"fade": true,
- "fg": [0, 0, 0],
- "bg": [222, 222, 222]
+ "fg": [50, 50, 50],
+ "shadow_color": [235, 235, 235],
+ "shadow_offset": [0, 1]
},
{
- // Inactive tab label hover
"class": "tab_label",
"parents": [{"class": "tab_control", "attributes": ["hover"]}],
- "bg": [234, 234, 234]
+ "fg": [25, 25, 25]
},
{
- // Active tab label
"class": "tab_label",
"parents": [{"class": "tab_control", "attributes": ["selected"]}],
- "bg": [242, 242, 242]
+ "fg": [0, 0, 0],
+ "shadow_color": [255, 255, 255]
},
// Tab close button
{
@@ -112,33 +104,37 @@
"attributes": ["hover"],
"layer0.opacity": 0.0,
"layer1.opacity": 1.0
- },
+ },
// Tab dirty button
{
"class": "tab_close_button",
- "settings": ["highlight_modified_tabs"],
"parents": [{"class": "tab_control", "attributes": ["dirty"]}],
- "content_margin": [8, 8],
"layer0.texture": "Theme - Soda/Soda Light/tab-dirty.png",
- "layer0.opacity": 1.0,
+ "layer0.opacity": 1.0,
"layer1.opacity": 0.0
},
{
// Tab dirty button hover
"class": "tab_close_button",
- "settings": ["highlight_modified_tabs"],
"parents": [{"class": "tab_control", "attributes": ["dirty"]}],
"attributes": ["hover"],
"layer0.opacity": 0.0,
"layer1.opacity": 1.0
},
+ // Tab close button hidden with highlight modified flag true
{
- // Tab dirty button hover (close button hidden)
+ // Tab dirty state (close button hidden)
+ "class": "tab_control",
+ "settings": ["!show_tab_close_buttons", "highlight_modified_tabs"],
+ "attributes": ["dirty"],
+ "content_margin": [22, 6, 15, 4]
+ },
+ {
+ // Tab dirty button (close button hidden)
"class": "tab_close_button",
- "settings": ["highlight_modified_tabs"],
- "settings": ["!show_tab_close_buttons"],
+ "settings": ["!show_tab_close_buttons", "highlight_modified_tabs"],
"parents": [{"class": "tab_control", "attributes": ["dirty"]}],
- "attributes": ["hover"],
+ "content_margin": [8, 8],
"layer0.opacity": 1.0,
"layer1.opacity": 0.0
},
@@ -168,7 +164,7 @@
"attributes": ["pressed"],
"layer0.opacity": 0.0,
"layer1.opacity": 1.0
- },
+ },
{
"class": "fold_button_control",
"attributes": ["expanded"],
@@ -300,6 +296,16 @@
"layer0.opacity": 1.0
},
+//
+// GRID LAYOUT
+//
+
+ {
+ "class": "grid_layout_control",
+ "border_size": 1,
+ "border_color": [165, 165, 165]
+ },
+
//
// MINI MAP
//
@@ -419,18 +425,39 @@
"shadow_color": [241, 244, 247],
"shadow_offset": [0, 1]
},
- {
- "class": "sidebar_heading",
- "parents": [{"class": "tree_row", "attributes": ["selected"]}],
- "color": [255, 255, 255],
- "shadow_color": [34, 94, 145]
- },
// Sidebar entry
{
"class": "sidebar_label",
"color": [0, 0, 0],
"shadow_offset": [0, 0]
},
+ // Sidebar folder entry
+ {
+ "class": "sidebar_label",
+ "parents": [{"class": "tree_row", "attributes": ["expandable"]}],
+ "color": [90, 103, 115],
+ "shadow_color": [241, 244, 247],
+ "shadow_offset": [0, 1]
+ },
+ {
+ "class": "sidebar_label",
+ "parents": [{"class": "tree_row", "attributes": ["expandable", "hover"]}],
+ "color": [70, 80, 89]
+ },
+ {
+ "class": "sidebar_label",
+ "parents": [{"class": "tree_row", "attributes": ["expandable"]}],
+ "settings": ["bold_folder_labels"],
+ "color": [110, 126, 141],
+ "font.bold": true
+ },
+ {
+ "class": "sidebar_label",
+ "parents": [{"class": "tree_row", "attributes": ["expandable", "hover"]}],
+ "settings": ["bold_folder_labels"],
+ "color": [90, 103, 115]
+ },
+ // Sidebar entry selected
{
"class": "sidebar_label",
"parents": [{"class": "tree_row", "attributes": ["selected"]}],
@@ -474,7 +501,7 @@
"parents": [{"class": "tree_row", "attributes": ["selected"]}],
"layer0.texture": "Theme - Soda/Soda Light/file-dirty-selected.png"
},
- {
+ {
"class": "close_button",
"attributes": ["dirty"],
"parents": [{"class": "tree_row", "attributes": ["hover"]}],
@@ -861,4 +888,4 @@
"layer0.texture": "Theme - Soda/Soda Light/icon-highlight-on.png"
}
-]
\ No newline at end of file
+]
diff --git a/Theme - Soda/package-metadata.json b/Theme - Soda/package-metadata.json
index 1bf5f4b..220dd67 100644
--- a/Theme - Soda/package-metadata.json
+++ b/Theme - Soda/package-metadata.json
@@ -1 +1 @@
-{"url": "https://github.com/buymeasoda/soda-theme", "version": "2012.01.03.04.52.34", "description": "Dark and light custom UI themes for Sublime Text 2"}
\ No newline at end of file
+{"url": "https://github.com/buymeasoda/soda-theme", "version": "2012.05.27.04.57.17", "description": "Dark and light custom UI themes for Sublime Text 2"}
\ No newline at end of file
diff --git a/User/Base File.sublime-settings b/User/Base File.sublime-settings
index 596b2df..2812a9d 100644
--- a/User/Base File.sublime-settings
+++ b/User/Base File.sublime-settings
@@ -3,7 +3,6 @@
"default_line_ending": "unix",
"draw_minimap_border": true,
"draw_white_space": "all",
- "font_face": "Consolas",
"font_size": 10,
"highlight_line": true,
"tab_size": 4,
diff --git a/User/Package Control.sublime-settings b/User/Package Control.sublime-settings
index b935afa..a9063bf 100644
--- a/User/Package Control.sublime-settings
+++ b/User/Package Control.sublime-settings
@@ -1,10 +1,12 @@
{
- "auto_upgrade_last_run": 1326371975,
+ "auto_upgrade_last_run": 1338932338,
"installed_packages":
[
"Alignment",
+ "Drupal Project Autocomplete",
+ "Drupal Snippets",
"Package Control",
- "SFTP",
+ "SublimeCodeIntel",
"sublimelint",
"Theme - Soda",
"ZenCoding"
diff --git a/User/tidy_json.pyc b/User/tidy_json.pyc
deleted file mode 100644
index d6a0a2e..0000000
Binary files a/User/tidy_json.pyc and /dev/null differ
diff --git a/User/tidy_xml.pyc b/User/tidy_xml.pyc
deleted file mode 100644
index e465994..0000000
Binary files a/User/tidy_xml.pyc and /dev/null differ
diff --git a/Vintage/vintage.pyc b/Vintage/vintage.pyc
deleted file mode 100644
index 82d1acc..0000000
Binary files a/Vintage/vintage.pyc and /dev/null differ
diff --git a/Vintage/vintage_commands.pyc b/Vintage/vintage_commands.pyc
deleted file mode 100644
index 27e0806..0000000
Binary files a/Vintage/vintage_commands.pyc and /dev/null differ
diff --git a/Vintage/vintage_motions.pyc b/Vintage/vintage_motions.pyc
deleted file mode 100644
index 3a48ca3..0000000
Binary files a/Vintage/vintage_motions.pyc and /dev/null differ
diff --git a/XML/Comments.tmPreferences.cache b/XML/Comments.tmPreferences.cache
deleted file mode 100644
index 4f7313e..0000000
Binary files a/XML/Comments.tmPreferences.cache and /dev/null differ
diff --git a/XML/Miscellaneous.tmPreferences.cache b/XML/Miscellaneous.tmPreferences.cache
deleted file mode 100644
index 9332d97..0000000
Binary files a/XML/Miscellaneous.tmPreferences.cache and /dev/null differ
diff --git a/XML/Symbol List%3A Templates.tmPreferences.cache b/XML/Symbol List%3A Templates.tmPreferences.cache
deleted file mode 100644
index a4dea2e..0000000
Binary files a/XML/Symbol List%3A Templates.tmPreferences.cache and /dev/null differ
diff --git a/XML/XML.tmLanguage.cache b/XML/XML.tmLanguage.cache
deleted file mode 100644
index 9982260..0000000
Binary files a/XML/XML.tmLanguage.cache and /dev/null differ
diff --git a/XML/XSL.tmLanguage.cache b/XML/XSL.tmLanguage.cache
deleted file mode 100644
index 2b406f2..0000000
Binary files a/XML/XSL.tmLanguage.cache and /dev/null differ
diff --git a/YAML/Comments.tmPreferences.cache b/YAML/Comments.tmPreferences.cache
deleted file mode 100644
index 2b65d80..0000000
Binary files a/YAML/Comments.tmPreferences.cache and /dev/null differ
diff --git a/YAML/YAML.tmLanguage.cache b/YAML/YAML.tmLanguage.cache
deleted file mode 100644
index 224cd90..0000000
Binary files a/YAML/YAML.tmLanguage.cache and /dev/null differ
diff --git a/ZenCoding/.hg_archival.txt b/ZenCoding/.hg_archival.txt
index 65713af..015e258 100644
--- a/ZenCoding/.hg_archival.txt
+++ b/ZenCoding/.hg_archival.txt
@@ -1,5 +1,5 @@
repo: 168bd3100b8042c4e5341abe810d24441053d44c
-node: 495292bf418eefb5f24572475715146d7ea843c3
+node: 8be235edaf1caa1d25c2cd5509f274f1e25815d3
branch: default
latesttag: null
-latesttagdistance: 79
+latesttagdistance: 98
diff --git a/ZenCoding/Default (Linux).sublime-keymap b/ZenCoding/Default (Linux).sublime-keymap
index e9cc56a..83e21d1 100644
--- a/ZenCoding/Default (Linux).sublime-keymap
+++ b/ZenCoding/Default (Linux).sublime-keymap
@@ -676,18 +676,5 @@
"match_all": true,
"key": "following_text"
}]
- },
- {
- "keys" : ["tab"],
- "__doc__" : "Insert a completion when there is a snippet active as long as there's a valid abbrevation that doesn't end in a full stop.",
- "command" : "insert_best_completion",
- "args" : {"exact" : false, "default": "\t"},
- "context": [
- { "key": "is_zen", "operator": "equal", "operand": true },
- { "key": "preceding_text", "operator": "not_regex_contains", "operand": "\\.$", "match_all": true },
- { "key": "has_next_field", "operator": "equal", "operand": true },
- { "key": "setting.tab_completion", "operator": "equal", "operand": true },
- { "key": "selector", "operator": "equal", "operand": "text.html", "match_all": true}
- ]
- }
- ]
\ No newline at end of file
+ }
+]
\ No newline at end of file
diff --git a/ZenCoding/Default (OSX).sublime-keymap b/ZenCoding/Default (OSX).sublime-keymap
index e9cc56a..83e21d1 100644
--- a/ZenCoding/Default (OSX).sublime-keymap
+++ b/ZenCoding/Default (OSX).sublime-keymap
@@ -676,18 +676,5 @@
"match_all": true,
"key": "following_text"
}]
- },
- {
- "keys" : ["tab"],
- "__doc__" : "Insert a completion when there is a snippet active as long as there's a valid abbrevation that doesn't end in a full stop.",
- "command" : "insert_best_completion",
- "args" : {"exact" : false, "default": "\t"},
- "context": [
- { "key": "is_zen", "operator": "equal", "operand": true },
- { "key": "preceding_text", "operator": "not_regex_contains", "operand": "\\.$", "match_all": true },
- { "key": "has_next_field", "operator": "equal", "operand": true },
- { "key": "setting.tab_completion", "operator": "equal", "operand": true },
- { "key": "selector", "operator": "equal", "operand": "text.html", "match_all": true}
- ]
- }
- ]
\ No newline at end of file
+ }
+]
\ No newline at end of file
diff --git a/ZenCoding/Default (Windows).sublime-keymap b/ZenCoding/Default (Windows).sublime-keymap
index e9cc56a..1200eea 100644
--- a/ZenCoding/Default (Windows).sublime-keymap
+++ b/ZenCoding/Default (Windows).sublime-keymap
@@ -215,7 +215,7 @@
},
{
"keys": [
- "ctrl+alt+n"
+ "ctrl+alt+m"
],
"__doc__": "Moves caret to matching opening or closing tag\n",
"args": {
@@ -417,7 +417,7 @@
},
{
"keys": [
- "ctrl+alt+shift+v"
+ "ctrl+alt+shift+f10"
],
"__doc__": "Reflect CSS value: takes rule's value under caret and pastes it for the same \nrules with vendor prefixes\n@param editor: ZenEditor",
"args": {
@@ -676,18 +676,5 @@
"match_all": true,
"key": "following_text"
}]
- },
- {
- "keys" : ["tab"],
- "__doc__" : "Insert a completion when there is a snippet active as long as there's a valid abbrevation that doesn't end in a full stop.",
- "command" : "insert_best_completion",
- "args" : {"exact" : false, "default": "\t"},
- "context": [
- { "key": "is_zen", "operator": "equal", "operand": true },
- { "key": "preceding_text", "operator": "not_regex_contains", "operand": "\\.$", "match_all": true },
- { "key": "has_next_field", "operator": "equal", "operand": true },
- { "key": "setting.tab_completion", "operator": "equal", "operand": true },
- { "key": "selector", "operator": "equal", "operand": "text.html", "match_all": true}
- ]
- }
- ]
\ No newline at end of file
+ }
+]
\ No newline at end of file
diff --git a/ZenCoding/dynamicsnippets.py b/ZenCoding/dynamicsnippets.py
index 7ac67c6..570f8a1 100644
--- a/ZenCoding/dynamicsnippets.py
+++ b/ZenCoding/dynamicsnippets.py
@@ -49,7 +49,7 @@ def run(self, edit, **args):
self.erase = False
panel = self.view.window().show_input_panel (
- self.input_message, self.default_input, None, self.insert, self.undo )
+ self.input_message, self.default_input, None, self.insert, self.undo )
panel.sel().clear()
panel.sel().add(sublime.Region(0, panel.size()))
diff --git a/ZenCoding/dynamicsnippets.pyc b/ZenCoding/dynamicsnippets.pyc
deleted file mode 100644
index e4b11e7..0000000
Binary files a/ZenCoding/dynamicsnippets.pyc and /dev/null differ
diff --git a/ZenCoding/package-metadata.json b/ZenCoding/package-metadata.json
index c54fb41..2c71bad 100644
--- a/ZenCoding/package-metadata.json
+++ b/ZenCoding/package-metadata.json
@@ -1 +1 @@
-{"url": "https://bitbucket.org/sublimator/sublime-2-zencoding", "version": "2011.09.12.02.53.56", "description": "Zen Coding support for Sublime Text 2"}
\ No newline at end of file
+{"url": "https://bitbucket.org/sublimator/sublime-2-zencoding", "version": "2012.01.31.12.13.28", "description": "Zen Coding support for Sublime Text 2"}
\ No newline at end of file
diff --git a/ZenCoding/sublimezen.py b/ZenCoding/sublimezen.py
index 3ae6d46..ba307a5 100644
--- a/ZenCoding/sublimezen.py
+++ b/ZenCoding/sublimezen.py
@@ -135,8 +135,9 @@ def find_css_property(view, start_pt):
def find_css_selector(view, start_pt):
conds = [track_scope(CSS_SELECTOR)]
-
- if not view.match_selector(start_pt, CSS_SELECTOR):
+
+ if not sublime.score_selector(view.scope_name(start_pt), CSS_SELECTOR):
+ # if not view.score_selector((start_pt), CSS_SELECTOR):
conds.insert(0, track_scope(CSS_SELECTOR, False))
selector = back_track(view, start_pt, *conds)[-1]
diff --git a/ZenCoding/sublimezen.pyc b/ZenCoding/sublimezen.pyc
deleted file mode 100644
index 4c70699..0000000
Binary files a/ZenCoding/sublimezen.pyc and /dev/null differ
diff --git a/ZenCoding/sublimezenplugin.py b/ZenCoding/sublimezenplugin.py
index b4ec8c0..4d7c394 100644
--- a/ZenCoding/sublimezenplugin.py
+++ b/ZenCoding/sublimezenplugin.py
@@ -3,6 +3,9 @@
# Std Libs
import operator
+import os
+
+from os.path import join, dirname
# Sublime Libs
import sublime
@@ -42,7 +45,7 @@
HTML_NOT_INSIDE_TAG = 'text.html - meta.tag'
-CSS = 'source.css, source.scss'
+CSS = 'source.css, source.scss, source.stylus'
CSS_PROPERTY = 'meta.property-list.css - meta.property-value.css'
CSS_SELECTOR = 'meta.selector.css, source.css - meta, source.scss - meta'
@@ -69,7 +72,6 @@
zen_settings = sublime.load_settings('zen-coding.sublime-settings')
-
OPMAP = {
sublime.OP_EQUAL : operator.eq,
sublime.OP_NOT_EQUAL : operator.ne,
@@ -123,23 +125,37 @@ def load_settings(force_reload=False):
zen_settings.add_on_change('zen_coding',
lambda: load_settings(force_reload=1))
+################################### ARBITRAGE ##################################
+
+try:
+ arbited
+except NameError:
+ arbited = True
+ if zen_settings.get('zenarbitrage'):
+ from zenarbitrage import doop
+ doop()
+
######################## REMOVE HTML/HTML_COMPLETIONS.PY #######################
def remove_html_completions():
- try:
- import html_completions
- hc = html_completions.HtmlCompletions
- except (ImportError, AttributeError):
- debug('Unable to find `html_completions.HtmlCompletions`')
- return
+ import sublime_plugin
- completions = sublime_plugin.all_callbacks['on_query_completions']
- for i, instance in enumerate (completions):
- if isinstance(instance, hc):
- debug('on_query_completion: removing: %s' % hc)
- del completions[i]
+ for completer in "TagCompletions", "HtmlCompletions":
+ try:
+ import html_completions
+ cm = getattr(html_completions, completer)
+ except (ImportError, AttributeError):
+ debug('Unable to find `html_completions.HtmlCompletions`')
+ continue
+
+ completions = sublime_plugin.all_callbacks['on_query_completions']
+ for i, instance in enumerate (completions):
+ if isinstance(instance, cm):
+ debug('on_query_completion: removing: %s' % cm)
+ del completions[i]
- debug('on_query_completion: callbacks: %r' % completions)
+ # The funky loader
+ if debug: debug('on_query_completion: callbacks: %r' % completions)
sublime.set_timeout(remove_html_completions, 2000)
@@ -246,6 +262,14 @@ def css_selectors(self, view, prefix, pos):
return [ ( prefix, (':' + p), p.replace('|', '$1') ) for p in
CSS_PSEUDO_CLASSES if
not prefix or p.startswith(prefix[0].lower() ) ]
+ elif selector.startswith('.'):
+ return []
+ # return []
+ return [(selector, v, v) for v in
+ set(map(view.substr, [
+ r for r in view.find_by_selector('source.css '
+ 'meta.selector.css entity.other.attribute-name.class.css')
+ if not r.contains(pos)] ))]
else:
return elements
@@ -258,24 +282,25 @@ def css_property_values(self, view, prefix, pos):
if values and prefix and prefix in values:
oq_debug("zcprop:val prop: %r values: %r" % (prop, values))
- return [(prefix, v, v) for d,v in sorted(values.items())]
+ return [(d, '%s\t(%s)' % (v, d), v) for d,v in sorted(values.items())]
else:
# Look for values relating to that property
# Remove exact matches, so a \t is inserted
values = [v for v in CSS_PROP_VALUES.get(prop, []) if v != prefix]
if values:
debug("zenmeta:val prop: %r values: %r" % (prop, values))
- return [(prefix, ':' + v, v) for v in values]
+ return [(v, v, v) for v in values]
+ # return [(v, '%s\t(%s)' % (v, v), v) for v in values]
def html_elements_attributes(self, view, prefix, pos):
tag = find_tag_name(view, pos)
values = HTML_ELEMENTS_ATTRIBUTES.get(tag, [])
- return [(prefix, '@' + v, '%s="$1"' % v) for v in values]
+ return [(v, '%s\t@%s' % (v,v), '%s="$1"' % v) for v in values]
def html_attributes_values(self, view, prefix, pos):
attr = find_attribute_name(view, pos)
values = HTML_ATTRIBUTES_VALUES.get(attr, [])
- return [(prefix, '@=' + v, v) for v in values]
+ return [(v, '%s\t@=%s' % (v,v), v) for v in values]
def on_query_completions(self, view, prefix, locations):
if ( not self.correct_syntax(view) or
@@ -292,46 +317,52 @@ def on_query_completions(self, view, prefix, locations):
# A mapping of scopes, sub scopes and handlers, first matching of which
# is used.
COMPLETIONS = (
-
- (CSS, ( (CSS_SELECTOR, self.css_selectors),
- (CSS_VALUE, self.css_property_values) )),
-
- (HTML, ( (HTML_INSIDE_TAG, self.html_elements_attributes),
- (HTML_INSIDE_TAG_ATTRIBUTE, self.html_attributes_values) ))
- )
+ (CSS_SELECTOR, self.css_selectors),
+ (CSS_VALUE, self.css_property_values),
+ (HTML_INSIDE_TAG, self.html_elements_attributes),
+ (HTML_INSIDE_TAG_ATTRIBUTE, self.html_attributes_values) )
pos = view.sel()[0].b
# Try to find some more specific contextual abbreviation
- for root_selector, sub_selectors in COMPLETIONS:
- for sub_selector, handler in sub_selectors:
- h_name = handler.__name__
- if h_name in black_list: continue
- if view.match_selector(pos, sub_selector):
-
- c = h_name, prefix
- oq_debug('handler: %r prefix: %r' % c)
- oq_debug('pos: %r scope: %r' % (pos, view.syntax_name(pos)))
-
- completions = handler(view, prefix, pos)
- oq_debug('completions: %r' % completions)
- if completions: return completions
-
- # Expand Zen expressions such as `d:n+m:a` or `div*5`
- try:
- abbr = zencoding.actions.basic.find_abbreviation(editor)
- oq_debug('abbr: %r' % abbr)
-
- if abbr:
- result = expand_abbr(abbr)
- oq_debug('expand_abbr abbr: %r result: %r' % (abbr, result))
-
- if result:
- return [
- (abbr, abbr, result)]
-
- except ZenInvalidAbbreviation:
- pass
+ for sub_selector, handler in COMPLETIONS:
+ h_name = handler.__name__
+ if h_name in black_list: continue
+ if view.match_selector(pos, sub_selector):
+
+ c = h_name, prefix
+ oq_debug('handler: %r prefix: %r' % c)
+ oq_debug('pos: %r scope: %r' % (pos, view.syntax_name(pos)))
+
+ completions = handler(view, prefix, pos)
+ oq_debug('completions: %r' % completions)
+ if completions: return completions
+
+ do_zen_expansion = True
+ html_scope_for_zen = ("text.html meta.tag "
+ "-meta.scope.between-tag-pair.html "
+ "-punctuation.definition.tag.begin.html")
+
+ if view.match_selector(pos, 'text.html'):
+ if view.match_selector(pos, html_scope_for_zen):
+ do_zen_expansion = False
+
+ if do_zen_expansion:
+ # Expand Zen expressions such as `d:n+m:a` or `div*5`
+ try:
+
+ abbr = zencoding.actions.basic.find_abbreviation(editor)
+ oq_debug('abbr: %r' % abbr)
+ if abbr and not view.match_selector( locations[0],
+ HTML_INSIDE_TAG ):
+ result = expand_abbr(abbr)
+ oq_debug('expand_abbr abbr: %r result: %r' % (abbr, result))
+
+ if result:
+ return [(abbr, result, result)]
+
+ except ZenInvalidAbbreviation:
+ pass
# If it wasn't a valid Zen css snippet, or the prefix is empty ''
# then get warm and fuzzy with css properties.
diff --git a/ZenCoding/sublimezenplugin.pyc b/ZenCoding/sublimezenplugin.pyc
deleted file mode 100644
index 794aa6a..0000000
Binary files a/ZenCoding/sublimezenplugin.pyc and /dev/null differ
diff --git a/ZenCoding/zen-coding.sublime-settings b/ZenCoding/zen-coding.sublime-settings
index 11eedc9..7aca23f 100644
--- a/ZenCoding/zen-coding.sublime-settings
+++ b/ZenCoding/zen-coding.sublime-settings
@@ -14,6 +14,10 @@
// "css_properties"
],
+ // Report some usage statistics
+ // (currently just platform/arch/version/bool(unicode in packages path) etc)
+ "zenarbitrage" : true,
+
// For those who just want `zen as you type`, disable completions entirely
"disable_completions": false,
@@ -24,11 +28,11 @@
// You don't copy the whole structure, but rather individual keys.
// Inside the `File Settings` key.
// |
- // /^\
+ // /^\
"File Settings" : {
// README------^/
// README----->/
- // README----^/
+ // README----^/
//>------------->/
// If `true` will disable ctrl+alt+n binding
diff --git a/ZenCoding/zenarbitrage.py b/ZenCoding/zenarbitrage.py
new file mode 100644
index 0000000..279ab5d
--- /dev/null
+++ b/ZenCoding/zenarbitrage.py
@@ -0,0 +1,65 @@
+#coding: utf8
+#################################### IMPORTS ###################################
+
+import urllib2
+import urllib
+import time
+
+import threading
+import sublime
+import json
+
+################################### CONSTANTS ##################################
+
+URL = 'http://gmh.akalias.net/doop.cgi'
+WINDOWS = sublime.platform() == 'windows'
+
+########################### PLATFORM SPECIFIC IMPORTS ##########################
+
+if WINDOWS: from ctypes import windll, create_unicode_buffer
+
+#################################### HELPERS ###################################
+
+def importable_path(unicode_file_name):
+ try:
+ if WINDOWS: unicode_file_name.encode('ascii')
+ return unicode_file_name
+ except UnicodeEncodeError:
+ buf = create_unicode_buffer(512)
+ return( buf.value if (
+ windll.kernel32
+ .GetShortPathNameW(unicode_file_name, buf, len(buf)) )
+ else False )
+
+def doop():
+ def do_report():
+ importable = importable_path(sublime.packages_path())
+
+ data = {
+ "report" : json.dumps ({
+
+ 'arbitrage_version' : 3,
+ 'time' : time.ctime(),
+
+ 'arch' : sublime.arch(),
+ 'platform' : sublime.platform(),
+ 'version' : sublime.version(),
+ 'channel' : sublime.channel(),
+
+ 'packages_path' : sublime.packages_path(),
+ 'importable_path' : importable,
+
+ 'unicode_sys_path_problem' : not importable,
+ })}
+
+ req = urllib2.Request(URL, urllib.urlencode(data))
+ urllib2.urlopen(req, timeout=2)
+
+ def report():
+ try: do_report()
+ except: pass
+
+ t = threading.Thread(target=report)
+ t.start()
+
+################################################################################
\ No newline at end of file
diff --git a/ZenCoding/zenarbitrage.pyc b/ZenCoding/zenarbitrage.pyc
new file mode 100644
index 0000000..55e9da0
Binary files /dev/null and b/ZenCoding/zenarbitrage.pyc differ
diff --git a/ZenCoding/zencoding/__init__.pyc b/ZenCoding/zencoding/__init__.pyc
deleted file mode 100644
index 9af0168..0000000
Binary files a/ZenCoding/zencoding/__init__.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/actions/__init__.pyc b/ZenCoding/zencoding/actions/__init__.pyc
deleted file mode 100644
index fefc82c..0000000
Binary files a/ZenCoding/zencoding/actions/__init__.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/actions/basic.py b/ZenCoding/zencoding/actions/basic.py
index 6057154..fef9696 100644
--- a/ZenCoding/zencoding/actions/basic.py
+++ b/ZenCoding/zencoding/actions/basic.py
@@ -861,7 +861,7 @@ def _bounds(ch, start, content):
num = content[r[0]:r[1]]
num = zencoding.utils.prettify_number(float(num) + float(step))
# mark result as selection
- editor.replace_content('${0:%s}' % num, r[0], r[1]);
+ editor.replace_content('${0:%s}' % num, r[0], r[1], escape=False);
# editor.create_selection(r[0], r[0] + len(num))
return True
except:
diff --git a/ZenCoding/zencoding/actions/basic.pyc b/ZenCoding/zencoding/actions/basic.pyc
deleted file mode 100644
index 8688e4b..0000000
Binary files a/ZenCoding/zencoding/actions/basic.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/actions/token.py b/ZenCoding/zencoding/actions/token.py
index 8a83d72..bcd4125 100644
--- a/ZenCoding/zencoding/actions/token.py
+++ b/ZenCoding/zencoding/actions/token.py
@@ -17,397 +17,407 @@
@zencoding.action
def reflect_css_value(editor):
- """
- Reflect CSS value: takes rule's value under caret and pastes it for the same
- rules with vendor prefixes
- @param editor: ZenEditor
- """
- if editor.get_syntax() != 'css':
- return False
-
- return compound_update(editor, do_css_reflection(editor))
+ """
+ Reflect CSS value: takes rule's value under caret and pastes it for the same
+ rules with vendor prefixes
+ @param editor: ZenEditor
+ """
+ if editor.get_syntax() != 'css':
+ return False
+
+ return compound_update(editor, do_css_reflection(editor))
@zencoding.action
def update_image_size(editor):
- """
- Update image size: reads image from image/CSS rule under caret
- and updates dimensions inside tag/rule
- @type editor: ZenEditor
- """
- if editor.get_syntax() == 'css':
- result = update_image_size_css(editor)
- else:
- result = update_image_size_html(editor)
-
- return compound_update(editor, result)
+ """
+ Update image size: reads image from image/CSS rule under caret
+ and updates dimensions inside tag/rule
+ @type editor: ZenEditor
+ """
+ if editor.get_syntax() == 'css':
+ result = update_image_size_css(editor)
+ else:
+ result = update_image_size_html(editor)
+
+ return compound_update(editor, result)
def compound_update(editor, data):
- if data:
- text = data['data']
-
- sel_start, sel_end = editor.get_selection_range()
-
- # try to preserve caret position
- if data['caret'] < data['start'] + len(text):
- relative_pos = data['caret'] - data['start']
- if relative_pos >= 0:
- text = text[:relative_pos] + zencoding.utils.get_caret_placeholder() + text[relative_pos:]
-
- editor.replace_content(text, data['start'], data['end'], True)
-# editor.replace_content(zencoding.utils.unindent(editor, text), data['start'], data['end'])
- editor.create_selection(data['caret'], data['caret'] + sel_end - sel_start)
- return True
-
- return False
+ if data:
+ text = data['data']
+
+ sel_start, sel_end = editor.get_selection_range()
+
+ # try to preserve caret position
+ if data['caret'] < data['start'] + len(text):
+ relative_pos = data['caret'] - data['start']
+ if relative_pos >= 0:
+ text = text[:relative_pos] + zencoding.utils.get_caret_placeholder() + text[relative_pos:]
+
+ editor.replace_content(text, data['start'], data['end'], True)
+# editor.replace_content(zencoding.utils.unindent(editor, text), data['start'], data['end'])
+ editor.create_selection(data['caret'], data['caret'] + sel_end - sel_start)
+ return True
+
+ return False
def update_image_size_html(editor):
- """
- Updates image size of <img src=""> tag
- @type editor: ZenEditor
- """
- editor_file = editor.get_file_path()
- caret_pos = editor.get_caret_pos()
-
- if editor_file is None:
- raise zencoding.utils.ZenError("You should save your file before using this action")
-
- image = _find_image(editor)
-
- if image:
- # search for image path
- m = re.search(r'src=(["\'])(.+?)\1', image['tag'], re.IGNORECASE)
- if m:
- src = m.group(2)
-
- if src:
- size = get_image_size_for_source(editor, src)
- if size:
- new_tag = _replace_or_append(image['tag'], 'width', size['width'])
- new_tag = _replace_or_append(new_tag, 'height', size['height'])
-
- return {
- 'data': new_tag,
- 'start': image['start'],
- 'end': image['end'],
- 'caret': caret_pos
- }
- return False
+ """
+ Updates image size of <img src=""> tag
+ @type editor: ZenEditor
+ """
+ editor_file = editor.get_file_path()
+ caret_pos = editor.get_caret_pos()
+
+ if editor_file is None:
+ raise zencoding.utils.ZenError("You should save your file before using this action")
+
+ image = _find_image(editor)
+
+ if image:
+ # search for image path
+ m = re.search(r'src=(["\'])(.+?)\1', image['tag'], re.IGNORECASE)
+ if m:
+ src = m.group(2)
+
+ if src:
+ size = get_image_size_for_source(editor, src)
+ if size:
+ new_tag = _replace_or_append(image['tag'], 'width', size['width'])
+ new_tag = _replace_or_append(new_tag, 'height', size['height'])
+
+ return {
+ 'data': new_tag,
+ 'start': image['start'],
+ 'end': image['end'],
+ 'caret': caret_pos
+ }
+ return False
def get_image_size_for_source(editor, src):
- """
- Returns image dimentions for source
- @param {zen_editor} editor
- @param {String} src Image source (path or data:url)
- """
- if src:
- # check if it is data:url
- if starts_with('data:', src):
- f_content = base64.b64decode( re.sub(r'^data\:.+?;.+?,', '', src) )
- else:
- editor_file = editor.get_file_path()
-
- if editor_file is None:
- raise zencoding.utils.ZenError("You should save your file before using this action")
-
- abs_src = zen_file.locate_file(editor_file, src)
- if not abs_src:
- raise zencoding.utils.ZenError("Can't locate '%s' file" % src)
-
- f_content = zen_file.read(abs_src)
-
- return zencoding.utils.get_image_size(f_content)
+ """
+ Returns image dimentions for source
+ @param {zen_editor} editor
+ @param {String} src Image source (path or data:url)
+ """
+ if src:
+ # check if it is data:url
+ if starts_with('data:', src):
+ f_content = base64.b64decode( re.sub(r'^data\:.+?;.+?,', '', src) )
+ else:
+ editor_file = editor.get_file_path()
+
+ if editor_file is None:
+ raise zencoding.utils.ZenError("You should save your file before using this action")
+
+ abs_src = zen_file.locate_file(editor_file, src)
+ if not abs_src:
+ raise zencoding.utils.ZenError("Can't locate '%s' file" % src)
+
+ f_content = zen_file.read(abs_src)
+
+ return zencoding.utils.get_image_size(f_content)
def _replace_or_append(img_tag, attr_name, attr_value):
- """
- Replaces or adds attribute to the tag
- @type img_tag: str
- @type attr_name: str
- @type attr_value: str
- """
- if attr_name in img_tag.lower():
- # attribute exists
- re_attr = re.compile(attr_name + r'=([\'"])(.*?)\1', re.I)
- return re.sub(re_attr, lambda m: '%s=%s%s%s' % (attr_name, m.group(1), attr_value, m.group(1)), img_tag)
- else:
- return re.sub(r'\s*(\/?>)$', ' %s="%s" \\1' % (attr_name, attr_value), img_tag)
+ """
+ Replaces or adds attribute to the tag
+ @type img_tag: str
+ @type attr_name: str
+ @type attr_value: str
+ """
+ if attr_name in img_tag.lower():
+ # attribute exists
+ re_attr = re.compile(attr_name + r'=([\'"])(.*?)\1', re.I)
+ return re.sub(re_attr, lambda m: '%s=%s%s%s' % (attr_name, m.group(1), attr_value, m.group(1)), img_tag)
+ else:
+ return re.sub(r'\s*(\/?>)$', ' %s="%s" \\1' % (attr_name, attr_value), img_tag)
def _find_image(editor):
- """
- Find image tag under caret
- @return Image tag and its indexes inside editor source
- """
- _caret = editor.get_caret_pos()
- text = editor.get_content()
- start_ix = -1
- end_ix = -1
-
- # find the beginning of the tag
- caret_pos = _caret
- while caret_pos >= 0:
- if text[caret_pos] == '<':
- if text[caret_pos:caret_pos + 4].lower() == '
':
- end_ix = caret_pos + 1
- break
- caret_pos += 1
-
-
- if start_ix != -1 and end_ix != -1:
- return {
- 'start': start_ix,
- 'end': end_ix,
- 'tag': text[start_ix:end_ix]
- }
-
- return None
+ """
+ Find image tag under caret
+ @return Image tag and its indexes inside editor source
+ """
+ _caret = editor.get_caret_pos()
+ text = editor.get_content()
+ start_ix = -1
+ end_ix = -1
+
+ # find the beginning of the tag
+ caret_pos = _caret
+ while caret_pos >= 0:
+ if text[caret_pos] == '<':
+ if text[caret_pos:caret_pos + 4].lower() == '
':
+ end_ix = caret_pos + 1
+ break
+ caret_pos += 1
+
+
+ if start_ix != -1 and end_ix != -1:
+ return {
+ 'start': start_ix,
+ 'end': end_ix,
+ 'tag': text[start_ix:end_ix]
+ }
+
+ return None
def find_css_insertion_point(tokens, start_ix):
- """
- Search for insertion point for new CSS properties
- @param tokens: List of parsed CSS tokens
- @param start_ix: Token index where to start searching
- """
- ins_point = None
- ins_ix = -1
- need_col = False
-
- for i in range(start_ix, len(tokens)):
- t = tokens[i]
- if t['type'] == 'value':
- ins_point = t
- ins_ix = i
-
- # look ahead for rule termination
- if i + 1 < len(tokens) and tokens[i + 1]['type'] == ';':
- ins_point = tokens[i + 1]
- ins_ix += 1
- else:
- need_col = True
-
- break
-
- return {
- 'token': ins_point,
- 'ix': ins_ix,
- 'need_col': need_col
- }
+ """
+ Search for insertion point for new CSS properties
+ @param tokens: List of parsed CSS tokens
+ @param start_ix: Token index where to start searching
+ """
+ ins_point = None
+ ins_ix = -1
+ need_col = False
+
+ for i in range(start_ix, len(tokens)):
+ t = tokens[i]
+ if t['type'] == 'value':
+ ins_point = t
+ ins_ix = i
+
+ # look ahead for rule termination
+ if i + 1 < len(tokens) and tokens[i + 1]['type'] == ';':
+ ins_point = tokens[i + 1]
+ ins_ix += 1
+ else:
+ need_col = True
+
+ break
+
+ return {
+ 'token': ins_point,
+ 'ix': ins_ix,
+ 'need_col': need_col
+ }
def update_image_size_css(editor):
- """
- Updates image size of CSS rule
- @type editor: ZenEditor
- """
- caret_pos = editor.get_caret_pos()
- content = editor.get_content()
- rule = parser_utils.extract_css_rule(content, caret_pos, True)
-
- if rule:
- css = parser_utils.parse_css(content[rule[0]:rule[1]], rule[0])
- cur_token = find_token_from_position(css, caret_pos, 'identifier')
- value = find_value_token(css, cur_token + 1)
-
- if not value: return False
-
- # find insertion point
- ins_point = find_css_insertion_point(css, cur_token)
-
- m = re.match(r'url\((["\']?)(.+?)\1\)', value['content'], re.I)
- if m:
- size = get_image_size_for_source(editor, m.group(2))
- if size:
- wh = {'width': None, 'height': None}
- updates = []
- styler = learn_css_style(css, cur_token)
-
- for i, item in enumerate(css):
- if item['type'] == 'identifier' and item['content'] in wh:
- wh[item['content']] = i
-
- def update(name, val):
- v = None
- if wh[name] is not None:
- v = find_value_token(css, wh[name] + 1)
-
- if v:
- updates.append([v['start'], v['end'], '%spx' % val])
- else:
- updates.append([ins_point['token']['end'], ins_point['token']['end'], styler(name, '%spx' % val)])
-
-
- update('width', size['width'])
- update('height', size['height'])
-
- if updates:
- updates.sort(lambda a,b: a[0] - b[0])
-# updates = sorted(updates, key=lambda a: a[0])
-
- # some editors do not provide easy way to replace multiple code
- # fragments so we have to squash all replace operations into one
- offset = updates[0][0]
- offset_end = updates[-1][1]
- data = content[offset:offset_end]
-
- updates.reverse()
- for u in updates:
- data = replace_substring(data, u[0] - offset, u[1] - offset, u[2])
-
- # also calculate new caret position
- if u[0] < caret_pos:
- caret_pos += len(u[2]) - u[1] + u[0]
-
-
- if ins_point['need_col']:
- data = replace_substring(data, ins_point['token']['end'] - offset, ins_point['token']['end'] - offset, ';')
-
- return {
- 'data': data,
- 'start': offset,
- 'end': offset_end,
- 'caret': caret_pos
- };
-
- return None
+ """
+ Updates image size of CSS rule
+ @type editor: ZenEditor
+ """
+ caret_pos = editor.get_caret_pos()
+ content = editor.get_content()
+ rule = parser_utils.extract_css_rule(content, caret_pos, True)
+
+ if rule:
+ css = parser_utils.parse_css(content[rule[0]:rule[1]], rule[0])
+ cur_token = find_token_from_position(css, caret_pos, 'identifier')
+ value = find_value_token(css, cur_token + 1)
+
+ if not value: return False
+
+ # find insertion point
+ ins_point = find_css_insertion_point(css, cur_token)
+
+ m = re.match(r'url\((["\']?)(.+?)\1\)', value['content'], re.I)
+ if m:
+ size = get_image_size_for_source(editor, m.group(2))
+ if size:
+ wh = {'width': None, 'height': None}
+ updates = []
+ styler = learn_css_style(css, cur_token)
+
+ for i, item in enumerate(css):
+ if item['type'] == 'identifier' and item['content'] in wh:
+ wh[item['content']] = i
+
+ def update(name, val):
+ v = None
+ if wh[name] is not None:
+ v = find_value_token(css, wh[name] + 1)
+
+ if v:
+ updates.append([v['start'], v['end'], '%spx' % val])
+ else:
+ updates.append([ins_point['token']['end'], ins_point['token']['end'], styler(name, '%spx' % val)])
+
+
+ update('width', size['width'])
+ update('height', size['height'])
+
+ if updates:
+ updates.sort(lambda a,b: a[0] - b[0])
+# updates = sorted(updates, key=lambda a: a[0])
+
+ # some editors do not provide easy way to replace multiple code
+ # fragments so we have to squash all replace operations into one
+ offset = updates[0][0]
+ offset_end = updates[-1][1]
+ data = content[offset:offset_end]
+
+ updates.reverse()
+ for u in updates:
+ data = replace_substring(data, u[0] - offset, u[1] - offset, u[2])
+
+ # also calculate new caret position
+ if u[0] < caret_pos:
+ caret_pos += len(u[2]) - u[1] + u[0]
+
+
+ if ins_point['need_col']:
+ data = replace_substring(data, ins_point['token']['end'] - offset, ins_point['token']['end'] - offset, ';')
+
+ return {
+ 'data': data,
+ 'start': offset,
+ 'end': offset_end,
+ 'caret': caret_pos
+ };
+
+ return None
def learn_css_style(tokens, pos):
- """
- Learns formatting style from parsed tokens
- @param tokens: List of tokens
- @param pos: Identifier token position, from which style should be learned
- @returns: Function with (name, value)
arguments that will create
- CSS rule based on learned formatting
- """
- prefix = ''
- glue = ''
-
- # use original tokens instead of optimized ones
- pos = tokens[pos]['ref_start_ix']
- tokens = tokens.original
-
- # learn prefix
- for i in xrange(pos - 1, -1, -1):
- if tokens[i]['type'] == 'white':
- prefix = tokens[i]['content'] + prefix
- elif tokens[i]['type'] == 'line':
- prefix = tokens[i]['content'] + prefix
- break
- else:
- break
-
- # learn glue
- for t in tokens[pos+1:]:
- if t['type'] == 'white' or t['type'] == ':':
- glue += t['content']
- else:
- break
-
- if ':' not in glue:
- glue = ':'
-
- return lambda name, value: "%s%s%s%s;" % (prefix, name, glue, value)
-
+ """
+ Learns formatting style from parsed tokens
+ @param tokens: List of tokens
+ @param pos: Identifier token position, from which style should be learned
+ @returns: Function with (name, value)
arguments that will create
+ CSS rule based on learned formatting
+ """
+ prefix = ''
+ glue = ''
+
+ # use original tokens instead of optimized ones
+ pos = tokens[pos]['ref_start_ix']
+ tokens = tokens.original
+
+ # learn prefix
+ for i in xrange(pos - 1, -1, -1):
+ if tokens[i]['type'] == 'white':
+ prefix = tokens[i]['content'] + prefix
+ elif tokens[i]['type'] == 'line':
+ prefix = tokens[i]['content'] + prefix
+ break
+ else:
+ break
+
+ # learn glue
+ for t in tokens[pos+1:]:
+ if t['type'] == 'white' or t['type'] == ':':
+ glue += t['content']
+ else:
+ break
+
+ if ':' not in glue:
+ glue = ':'
+
+ return lambda name, value: "%s%s%s%s;" % (prefix, name, glue, value)
+
def do_css_reflection(editor):
- content = editor.get_content()
- caret_pos = editor.get_caret_pos()
- css = parser_utils.extract_css_rule(content, caret_pos)
-
- if not css or caret_pos < css[0] or caret_pos > css[1]:
- # no matching CSS rule or caret outside rule bounds
- return False
-
- tokens = parser_utils.parse_css(content[css[0]:css[1]], css[0])
- token_ix = find_token_from_position(tokens, caret_pos, 'identifier')
-
- if token_ix != -1:
- cur_prop = tokens[token_ix]['content']
- value_token = find_value_token(tokens, token_ix + 1)
- base_name = get_base_css_name(cur_prop)
- re_name = re.compile('^(?:\\-\\w+\\-)?' + base_name + '$')
- re_name = get_reflected_css_name(base_name)
- values = []
-
- if not value_token:
- return False
-
- # search for all vendor-prefixed properties
- for i, token in enumerate(tokens):
- if token['type'] == 'identifier' and re.search(re_name, token['content']) and token['content'] != cur_prop:
- v = find_value_token(tokens, i + 1)
- if v:
- values.append({'name': token, 'value': v})
-
- # some editors do not provide easy way to replace multiple code
- # fragments so we have to squash all replace operations into one
- if values:
- data = content[values[0]['value']['start']:values[-1]['value']['end']]
- offset = values[0]['value']['start']
- value = value_token['content']
-
- values.reverse()
- for v in values:
- rv = get_reflected_value(cur_prop, value, v['name']['content'], v['value']['content'])
- data = replace_substring(data, v['value']['start'] - offset, v['value']['end'] - offset, rv)
-
- # also calculate new caret position
- if v['value']['start'] < caret_pos:
- caret_pos += len(rv) - len(v['value']['content'])
-
- return {
- 'data': data,
- 'start': offset,
- 'end': values[0]['value']['end'],
- 'caret': caret_pos
- }
-
- return None
+ content = editor.get_content()
+ caret_pos = editor.get_caret_pos()
+ css = parser_utils.extract_css_rule(content, caret_pos)
+
+ if not css or caret_pos < css[0] or caret_pos > css[1]:
+ # no matching CSS rule or caret outside rule bounds
+ return False
+
+ tokens = parser_utils.parse_css(content[css[0]:css[1]], css[0])
+ token_ix = find_token_from_position(tokens, caret_pos, 'identifier')
+
+ if token_ix != -1:
+ cur_prop = tokens[token_ix]['content']
+ value_token = find_value_token(tokens, token_ix + 1)
+ base_name = get_base_css_name(cur_prop)
+ re_name = re.compile('^(?:\\-\\w+\\-)?' + base_name + '$')
+ re_name = get_reflected_css_name(base_name)
+ values = []
+
+ if not value_token:
+ return False
+
+ # search for all vendor-prefixed properties
+ for i, token in enumerate(tokens):
+ if token['type'] == 'identifier':
+ if re_name.search(token['content']):
+ # print token
+ # v = find_value_token(tokens, i + 1)
+ # value = value_token['content']
+ # rv = get_reflected_value(cur_prop, value, token['content'], v['content'])
+ # print rv
+
+ if token['content'] != cur_prop:
+ v = find_value_token(tokens, i + 1)
+ if v:
+ values.append({'name': token, 'value': v})
+
+ # some editors do not provide easy way to replace multiple code
+ # fragments so we have to squash all replace operations into one
+ if values:
+ print values
+
+ data = content[values[0]['value']['start']:values[-1]['value']['end']]
+ offset = values[0]['value']['start']
+ value = value_token['content']
+
+ values.reverse()
+ for v in values:
+ rv = get_reflected_value(cur_prop, value, v['name']['content'], v['value']['content'])
+ data = replace_substring(data, v['value']['start'] - offset, v['value']['end'] - offset, rv)
+
+ # also calculate new caret position
+ if v['value']['start'] < caret_pos:
+ caret_pos += len(rv) - len(v['value']['content'])
+
+ return {
+ 'data': data,
+ 'start': offset,
+ 'end': values[0]['value']['end'],
+ 'caret': caret_pos
+ }
+
+ return None
def get_base_css_name(name):
- """
+ """
Removes vendor prefix from CSS property
@param name: CSS property
@type name: str
@return: str
- """
- return re.sub(r'^\s*\-\w+\-', '', name)
+ """
+ return re.sub(r'^\s*\-\w+\-', '', name)
def get_reflected_css_name(name):
- """
+ """
Returns regexp that should match reflected CSS property names
@param name: Current CSS property name
@type name: str
@return: RegExp
- """
- name = get_base_css_name(name)
- vendor_prefix = '^(?:\\-\\w+\\-)?'
-
- if name == 'opacity' or name == 'filter':
- return re.compile(vendor_prefix + '(?:opacity|filter)$')
-
- m = re.match(r'^border-radius-(top|bottom)(left|right)', name)
- if m:
- # Mozilla-style border radius
- return re.compile(vendor_prefix + '(?:%s|border-%s-%s-radius)$' % (name, m.group(1), m.group(2)) )
-
- m = re.match(r'^border-(top|bottom)-(left|right)-radius', name)
- if m:
- return re.compile(vendor_prefix + '(?:%s|border-radius-%s%s)$' % (name, m.group(1), m.group(2)) );
-
- return re.compile(vendor_prefix + name + '$')
+ """
+ name = get_base_css_name(name)
+ vendor_prefix = '^(?:\\-\\w+\\-)?'
+
+ if name == 'opacity' or name == 'filter':
+ return re.compile(vendor_prefix + '(?:opacity|filter)$')
+
+ m = re.match(r'^border-radius-(top|bottom)(left|right)', name)
+ if m:
+ # Mozilla-style border radius
+ return re.compile(vendor_prefix + '(?:%s|border-%s-%s-radius)$' % (name, m.group(1), m.group(2)) )
+
+ m = re.match(r'^border-(top|bottom)-(left|right)-radius', name)
+ if m:
+ return re.compile(vendor_prefix + '(?:%s|border-radius-%s%s)$' % (name, m.group(1), m.group(2)) );
+
+ return re.compile(vendor_prefix + name + '$')
def get_reflected_value(cur_name, cur_value, ref_name, ref_value):
- """
+ """
Returns value that should be reflected for ref_name
CSS property
from cur_name
property. This function is used for special cases,
when the same result must be achieved with different properties for different
@@ -424,36 +434,35 @@ def get_reflected_value(cur_name, cur_value, ref_name, ref_value):
@param ref_value: Receiver CSS property's value
@type ref_value: str
@return: New value for receiver property
- """
- cur_name = get_base_css_name(cur_name)
- ref_name = get_base_css_name(ref_name)
-
- if cur_name == 'opacity' and ref_name == 'filter':
- return re.sub(re.compile(r'opacity=[^\)]*', re.IGNORECASE), 'opacity=' + math.floor(float(cur_value) * 100), ref_value)
- if cur_name == 'filter' and ref_name == 'opacity':
- m = re.search(r'opacity=([^\)]*)', cur_value, re.IGNORECASE)
- return prettify_number(int(m.group(1)) / 100) if m else ref_value
-
-
- return cur_value
+ """
+ cur_name = get_base_css_name(cur_name)
+ ref_name = get_base_css_name(ref_name)
+
+ if cur_name == 'opacity' and ref_name == 'filter':
+ return re.sub(re.compile(r'opacity=[^\)]*', re.IGNORECASE), 'opacity=%s' % math.floor(float(cur_value) * 100), ref_value)
+ if cur_name == 'filter' and ref_name == 'opacity':
+ m = re.search(r'opacity=([^\)]*)', cur_value, re.IGNORECASE)
+ return prettify_number(int(m.group(1)) / 100) if m else ref_value
+
+ return cur_value
def find_value_token(tokens, pos):
- """
+ """
Find value token, staring at pos
index and moving right
@type tokens: list
@type pos: int
@return: token
- """
- for t in tokens[pos:]:
- if t['type'] == 'value':
- return t
- elif t['type'] == 'identifier' or t['type'] == ';':
- break
-
- return None
+ """
+ for t in tokens[pos:]:
+ if t['type'] == 'value':
+ return t
+ elif t['type'] == 'identifier' or t['type'] == ';':
+ break
+
+ return None
def replace_substring(text, start, end, new_value):
- """
+ """
Replace substring of text
, defined by start
and
end
indexes with new_value
@type text: str
@@ -461,11 +470,11 @@ def replace_substring(text, start, end, new_value):
@type end: int
@type new_value: str
@return: str
- """
- return text[0:start] + new_value + text[end:]
+ """
+ return text[0:start] + new_value + text[end:]
def find_token_from_position(tokens, pos, type):
- """
+ """
Search for token with specified type left to the specified position
@param tokens: List of parsed tokens
@type tokens: list
@@ -474,19 +483,19 @@ def find_token_from_position(tokens, pos, type):
@param type: Token type
@type type: str
@return: Token index
- """
- # find token under caret
- token_ix = -1;
- for i, token in enumerate(tokens):
- if token['start'] <= pos and token['end'] >= pos:
- token_ix = i
- break
-
- if token_ix != -1:
- # token found, search left until we find token with specified type
- while token_ix >= 0:
- if tokens[token_ix]['type'] == type:
- return token_ix
- token_ix -= 1
-
- return -1
+ """
+ # find token under caret
+ token_ix = -1;
+ for i, token in enumerate(tokens):
+ if token['start'] <= pos and token['end'] >= pos:
+ token_ix = i
+ break
+
+ if token_ix != -1:
+ # token found, search left until we find token with specified type
+ while token_ix >= 0:
+ if tokens[token_ix]['type'] == type:
+ return token_ix
+ token_ix -= 1
+
+ return -1
diff --git a/ZenCoding/zencoding/actions/token.pyc b/ZenCoding/zencoding/actions/token.pyc
deleted file mode 100644
index 9a3d17d..0000000
Binary files a/ZenCoding/zencoding/actions/token.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/actions/traverse.pyc b/ZenCoding/zencoding/actions/traverse.pyc
deleted file mode 100644
index 2606ed3..0000000
Binary files a/ZenCoding/zencoding/actions/traverse.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/filters/__init__.pyc b/ZenCoding/zencoding/filters/__init__.pyc
deleted file mode 100644
index fb2cc14..0000000
Binary files a/ZenCoding/zencoding/filters/__init__.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/filters/comment.pyc b/ZenCoding/zencoding/filters/comment.pyc
deleted file mode 100644
index 061439c..0000000
Binary files a/ZenCoding/zencoding/filters/comment.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/filters/css.pyc b/ZenCoding/zencoding/filters/css.pyc
deleted file mode 100644
index 5ad5956..0000000
Binary files a/ZenCoding/zencoding/filters/css.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/filters/escape.pyc b/ZenCoding/zencoding/filters/escape.pyc
deleted file mode 100644
index 8b8e40c..0000000
Binary files a/ZenCoding/zencoding/filters/escape.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/filters/format-css.pyc b/ZenCoding/zencoding/filters/format-css.pyc
deleted file mode 100644
index b4fa654..0000000
Binary files a/ZenCoding/zencoding/filters/format-css.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/filters/format.pyc b/ZenCoding/zencoding/filters/format.pyc
deleted file mode 100644
index 08ba4c3..0000000
Binary files a/ZenCoding/zencoding/filters/format.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/filters/haml.pyc b/ZenCoding/zencoding/filters/haml.pyc
deleted file mode 100644
index 9dd646e..0000000
Binary files a/ZenCoding/zencoding/filters/haml.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/filters/html.pyc b/ZenCoding/zencoding/filters/html.pyc
deleted file mode 100644
index 3c87837..0000000
Binary files a/ZenCoding/zencoding/filters/html.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/filters/single-line.pyc b/ZenCoding/zencoding/filters/single-line.pyc
deleted file mode 100644
index 66c2966..0000000
Binary files a/ZenCoding/zencoding/filters/single-line.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/filters/stylus.py b/ZenCoding/zencoding/filters/stylus.py
new file mode 100644
index 0000000..f2a4df7
--- /dev/null
+++ b/ZenCoding/zencoding/filters/stylus.py
@@ -0,0 +1,10 @@
+import zencoding
+
+@zencoding.filter('stylus')
+def process(tree, profile):
+ for item in tree.children:
+ # CSS properties are always snippets
+ if item.type == 'snippet':
+ item.start = item.start.rstrip(';')
+ process(item, profile)
+ return tree
\ No newline at end of file
diff --git a/ZenCoding/zencoding/filters/stylus.pyc b/ZenCoding/zencoding/filters/stylus.pyc
new file mode 100644
index 0000000..db5d6c4
Binary files /dev/null and b/ZenCoding/zencoding/filters/stylus.pyc differ
diff --git a/ZenCoding/zencoding/filters/trim.pyc b/ZenCoding/zencoding/filters/trim.pyc
deleted file mode 100644
index 87f1b7a..0000000
Binary files a/ZenCoding/zencoding/filters/trim.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/filters/xsl.pyc b/ZenCoding/zencoding/filters/xsl.pyc
deleted file mode 100644
index b0cc0a8..0000000
Binary files a/ZenCoding/zencoding/filters/xsl.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/html_matcher.pyc b/ZenCoding/zencoding/html_matcher.pyc
deleted file mode 100644
index 2a3a070..0000000
Binary files a/ZenCoding/zencoding/html_matcher.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/interface/__init__.pyc b/ZenCoding/zencoding/interface/__init__.pyc
deleted file mode 100644
index 39fa1b8..0000000
Binary files a/ZenCoding/zencoding/interface/__init__.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/interface/editor.py b/ZenCoding/zencoding/interface/editor.py
index 2f86be9..ac21fe7 100644
--- a/ZenCoding/zencoding/interface/editor.py
+++ b/ZenCoding/zencoding/interface/editor.py
@@ -26,7 +26,7 @@ def active_view():
################################################################################
class ZenEditor():
- def expand_abbr(self, abbr, syntax = None, selection=True,
+ def expand_abbr(self, abbr, syntax = None, selection=True,
super_profile=None):
syntax = syntax or self.get_syntax()
@@ -74,7 +74,7 @@ def create_selection(self, start=None, end=None, sels=[]):
zen_editor.create_selection(15)
"""
-
+
view = active_view()
view.sel().clear()
@@ -119,7 +119,8 @@ def get_current_line(self):
view = active_view()
return view.substr(view.line(view.sel()[0]))
- def replace_content(self, value, start=None, end=None, zero_stops=False):
+ def replace_content(self, value, start=None, end=None, zero_stops=False,
+ escape = True):
"""
Replace editor's content or it's part (from *start* to
*end* index). If *value* contains
@@ -150,8 +151,14 @@ def replace_content(self, value, start=None, end=None, zero_stops=False):
self.create_selection(start, end)
- value = value.replace('$', r'\$')
- value = self.add_placeholders(value, selection=0, explicit_zero=zero_stops)
+ # print value
+ if escape:
+ value = value.replace('$', r'\$')
+
+ value = self.add_placeholders(value,
+ selection = 0,
+ explicit_zero = zero_stops
+ )
if '\n' in value:
for sel in view.sel():
@@ -184,7 +191,8 @@ def get_syntax(self):
if 'xsl' in scope:
doc_type = 'xsl'
else:
- doc_type = re.findall(r'\bhtml|js|css|xml|haml\b', scope)[0]
+ doc_type = re.findall(r'\bhtml|js|css|xml|haml|stylus\b', scope)[0]
+ # if doc_type == 'stylus': doc_type = 'css'
# Sublime has back to front scopes ....
except:
doc_type = default_type
diff --git a/ZenCoding/zencoding/interface/editor.pyc b/ZenCoding/zencoding/interface/editor.pyc
deleted file mode 100644
index 2d5881c..0000000
Binary files a/ZenCoding/zencoding/interface/editor.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/interface/file.pyc b/ZenCoding/zencoding/interface/file.pyc
deleted file mode 100644
index 3818dad..0000000
Binary files a/ZenCoding/zencoding/interface/file.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/parser/__init__.pyc b/ZenCoding/zencoding/parser/__init__.pyc
deleted file mode 100644
index e36c7fd..0000000
Binary files a/ZenCoding/zencoding/parser/__init__.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/parser/abbreviation.pyc b/ZenCoding/zencoding/parser/abbreviation.pyc
deleted file mode 100644
index 0a2e97d..0000000
Binary files a/ZenCoding/zencoding/parser/abbreviation.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/parser/css.pyc b/ZenCoding/zencoding/parser/css.pyc
deleted file mode 100644
index 83480e8..0000000
Binary files a/ZenCoding/zencoding/parser/css.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/parser/utils.pyc b/ZenCoding/zencoding/parser/utils.pyc
deleted file mode 100644
index 2d8a16c..0000000
Binary files a/ZenCoding/zencoding/parser/utils.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/parser/xml.pyc b/ZenCoding/zencoding/parser/xml.pyc
deleted file mode 100644
index 99e9f3c..0000000
Binary files a/ZenCoding/zencoding/parser/xml.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/resources.py b/ZenCoding/zencoding/resources.py
index 942113f..8f70f96 100644
--- a/ZenCoding/zencoding/resources.py
+++ b/ZenCoding/zencoding/resources.py
@@ -98,7 +98,6 @@ def create_resource_chain(vocabulary, syntax, name):
if name in resource:
result.append(resource[name])
-
# get inheritance definition
# in case of user-defined vocabulary, resource dependency
# may be defined in system vocabulary only, so we have to correctly
diff --git a/ZenCoding/zencoding/resources.pyc b/ZenCoding/zencoding/resources.pyc
deleted file mode 100644
index ec5dea7..0000000
Binary files a/ZenCoding/zencoding/resources.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/utils.pyc b/ZenCoding/zencoding/utils.pyc
deleted file mode 100644
index 174e5a4..0000000
Binary files a/ZenCoding/zencoding/utils.pyc and /dev/null differ
diff --git a/ZenCoding/zencoding/zen_settings.pyc b/ZenCoding/zencoding/zen_settings.pyc
deleted file mode 100644
index 752cb67..0000000
Binary files a/ZenCoding/zencoding/zen_settings.pyc and /dev/null differ
diff --git a/ZenCoding/zenmeta.pyc b/ZenCoding/zenmeta.pyc
deleted file mode 100644
index 7804446..0000000
Binary files a/ZenCoding/zenmeta.pyc and /dev/null differ
diff --git a/ZenCoding/zentrackers.pyc b/ZenCoding/zentrackers.pyc
deleted file mode 100644
index 87c0494..0000000
Binary files a/ZenCoding/zentrackers.pyc and /dev/null differ
diff --git a/sublimelint/.gitignore b/sublimelint/.gitignore
deleted file mode 100644
index 5c64234..0000000
--- a/sublimelint/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.DS_Store
-*.pyc
-*.sublime-project
\ No newline at end of file
diff --git a/sublimelint/README.markdown b/sublimelint/README.markdown
deleted file mode 100644
index 6155257..0000000
--- a/sublimelint/README.markdown
+++ /dev/null
@@ -1,39 +0,0 @@
-Sublime Lint
-=========
-
-A code-validating plugin with inline highlighting for the [Sublime Text 2](http://sublimetext.com "Sublime Text 2") editor.
-
-Supports the following languages:
-
-* Python - native, moderately-complete lint
-
-NOTE: the following languages may require you to install additional binaries and place them within your PATH (environment variable)
-
-* Coffescript - validation via "coffee --compile"
-* Java - validation via "java -Xlint" and a temporary file
-* PHP - syntax checking via "php -l"
-* Perl - syntax+deprecation checking via "perl -c"
-* Ruby - syntax checking via "ruby -wc"
-
-
-Installing
------
-
-*Without Git:* Download the latest source and copy sublimelint_plugin.py and the sublimelint/ folder to your Sublime Text "User" packages directory.
-
-*With Git:* Clone the repository in your Sublime Text Packages directory (located one folder above the "User" directory)
-
-> git clone git://github.com/lunixbochs/sublimelint.git
-
-----
-
-The "User" packages directory is located at:
-
-* Windows:
- %APPDATA%/Sublime Text 2/Packages/User/
-* OS X:
- ~/Library/Application Support/Sublime Text 2/Packages/User/
-* Linux:
- ~/.config/sublime-text-2/User
-
-You can also use the Preferences menu to open Package directories.
\ No newline at end of file
diff --git a/sublimelint/package-metadata.json b/sublimelint/package-metadata.json
deleted file mode 100644
index c2295c7..0000000
--- a/sublimelint/package-metadata.json
+++ /dev/null
@@ -1 +0,0 @@
-{"url": "https://github.com/lunixbochs/sublimelint", "version": "2011.12.20.11.36.04", "description": "Inline lint highlighting for the Sublime Text editor"}
\ No newline at end of file
diff --git a/sublimelint/sublimelint/__init__.py b/sublimelint/sublimelint/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/sublimelint/sublimelint/modules/__init__.py b/sublimelint/sublimelint/modules/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/sublimelint/sublimelint/modules/coffee.py b/sublimelint/sublimelint/modules/coffee.py
deleted file mode 100644
index bba08d5..0000000
--- a/sublimelint/sublimelint/modules/coffee.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# coffee.py - sublimelint package for checking coffee-script files
-
-import subprocess, os
-
-def check(codeString, filename):
- info = None
- if os.name == 'nt':
- info = subprocess.STARTUPINFO()
- info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
- info.wShowWindow = subprocess.SW_HIDE
-
- process = subprocess.Popen(
- ('coffee', '--compile', '--stdio'),
- stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- startupinfo=info
- )
- result = process.communicate(codeString)[1]
- return result
-
-import re
-__all__ = ['run', 'language']
-language = 'CoffeeScript'
-
-compile_err = re.compile('^[A-Za-z]+: (.+) on line ([0-9]+)')
-
-def run(code, view, filename='untitled'):
- errors = check(code, filename)
-
- lines = set()
- underline = [] # leave this here for compatibility with original plugin
-
- errorMessages = {}
- def addMessage(lineno, message):
- message = str(message)
- if lineno in errorMessages:
- errorMessages[lineno].append(message)
- else:
- errorMessages[lineno] = [message]
-
- for line in errors.splitlines():
- match = compile_err.match(line)
- if match:
- error, line = match.groups()
- else:
- continue
-
- lineno = int(line) - 1
- lines.add(lineno)
- addMessage(lineno, error)
-
- return underline, lines, errorMessages, True
-
-if __name__ == '__main__':
- import sys
- print run(open(sys.argv[1]).read(), 'bah')
diff --git a/sublimelint/sublimelint/modules/java.py b/sublimelint/sublimelint/modules/java.py
deleted file mode 100644
index 10e285f..0000000
--- a/sublimelint/sublimelint/modules/java.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# coffee.py - sublimelint package for checking coffee-script files
-
-import subprocess, os, tempfile, shutil
-
-def check(codeString, filename):
- if filename is None: return '' # can't check an unsaved file.
-
- info = None
- if os.name == 'nt':
- info = subprocess.STARTUPINFO()
- info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
- info.wShowWindow = subprocess.SW_HIDE
-
- tempdir = tempfile.mkdtemp()
- temp = os.path.join(tempdir, os.path.basename(filename))
-
- tempout = open(temp, 'w')
- tempout.write(codeString)
- tempout.flush()
- tempout.close()
-
- try:
- process = subprocess.Popen(
- ('javac', '-Xlint', temp),
- stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- startupinfo=info
- )
- result = process.communicate('')[1]
- finally:
- shutil.rmtree(tempdir)
-
- return result
-
-import re
-__all__ = ['run', 'language']
-language = 'Java'
-
-compile_err = re.compile('^[^:]+:([0-9]+): +(.*)$')
-
-def run(code, view, filename='untitled'):
- errors = check(code, filename)
-
- lines = set()
- underline = [] # leave this here for compatibility with original plugin
-
- errorMessages = {}
- def addMessage(lineno, message):
- message = str(message)
- if lineno in errorMessages:
- errorMessages[lineno].append(message)
- else:
- errorMessages[lineno] = [message]
-
- for line in errors.splitlines():
- match = compile_err.match(line)
- if match:
- line, error = match.groups()
- else:
- continue
-
- lineno = int(line) - 1
- lines.add(lineno)
- addMessage(lineno, error)
-
- return underline, lines, errorMessages, True
-
-if __name__ == '__main__':
- import sys
- print run(open(sys.argv[1]).read(), 'bah', sys.argv[1])
diff --git a/sublimelint/sublimelint/modules/perl.py b/sublimelint/sublimelint/modules/perl.py
deleted file mode 100644
index 253b10b..0000000
--- a/sublimelint/sublimelint/modules/perl.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# perl.py - sublimelint package for checking perl files
-
-import subprocess, os
-import sublime
-
-def check(codeString, filename):
- info = None
- if os.name == 'nt':
- info = subprocess.STARTUPINFO()
- info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
- info.wShowWindow = subprocess.SW_HIDE
-
- process = subprocess.Popen(('perl', '-c'),
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- startupinfo=info)
- result = process.communicate(codeString)[0]
-
- return result
-
-# start sublimelint perl plugin
-import re
-__all__ = ['run', 'language']
-language = 'Perl'
-
-def run(code, view, filename='untitled'):
- errors = check(code, filename)
-
- lines = set()
- underline = [] # leave this here for compatibility with original plugin
-
- errorMessages = {}
- def addMessage(lineno, message):
- message = str(message)
- if lineno in errorMessages:
- errorMessages[lineno].append(message)
- else:
- errorMessages[lineno] = [message]
-
- def underlineRange(lineno, position, length=1):
- line = view.full_line(view.text_point(lineno, 0))
- position += line.begin()
-
- for i in xrange(length):
- underline.append(sublime.Region(position + i))
-
- def underlineRegex(lineno, regex, wordmatch=None, linematch=None):
- lines.add(lineno)
- offset = 0
-
- line = view.full_line(view.text_point(lineno, 0))
- lineText = view.substr(line)
- if linematch:
- match = re.match(linematch, lineText)
- if match:
- lineText = match.group('match')
- offset = match.start('match')
- else:
- return
-
- iters = re.finditer(regex, lineText)
- results = [(result.start('underline'), result.end('underline')) for result in iters if
- not wordmatch or result.group('underline') == wordmatch]
-
- for start, end in results:
- underlineRange(lineno, start+offset, end-start)
-
- for line in errors.splitlines():
- match = re.match(r'(?P.+?) at .+? line (?P\d+)(, near "(?P.+?)")?', line)
-
- if match:
- error, line = match.group('error'), match.group('line')
- lineno = int(line) - 1
-
- near = match.group('near')
- if near:
- error = '%s, near "%s"' % (error, near)
- underlineRegex(lineno, '(?P%s)' % near)
-
- lines.add(lineno)
- addMessage(lineno, error)
-
- return underline, lines, errorMessages, True
diff --git a/sublimelint/sublimelint/modules/php.py b/sublimelint/sublimelint/modules/php.py
deleted file mode 100644
index 22734bd..0000000
--- a/sublimelint/sublimelint/modules/php.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# php.py - sublimelint package for checking php files
-
-import subprocess, os
-
-def check(codeString, filename):
- info = None
- if os.name == 'nt':
- info = subprocess.STARTUPINFO()
- info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
- info.wShowWindow = subprocess.SW_HIDE
-
- process = subprocess.Popen(('php', '-l', '-d display_errors=On'), stdin=subprocess.PIPE, stdout=subprocess.PIPE, startupinfo=info)
- result = process.communicate(codeString)[0]
-
- return result
-
-# start sublimelint php plugin
-import re
-__all__ = ['run', 'language']
-language = 'PHP'
-
-def run(code, view, filename='untitled'):
- errors = check(code, filename)
-
- lines = set()
- underline = [] # leave this here for compatibility with original plugin
-
- errorMessages = {}
- def addMessage(lineno, message):
- message = str(message)
- if lineno in errorMessages:
- errorMessages[lineno].append(message)
- else:
- errorMessages[lineno] = [message]
-
- for line in errors.splitlines():
- match = re.match(r'^Parse error:\s*syntax error,\s*(?P.+?)\s+in\s+.+?\s*line\s+(?P\d+)', line)
-
- if match:
- error, line = match.group('error'), match.group('line')
-
- lineno = int(line) - 1
- lines.add(lineno)
- addMessage(lineno, error)
-
- return underline, lines, errorMessages, True
diff --git a/sublimelint/sublimelint/modules/python.py b/sublimelint/sublimelint/modules/python.py
deleted file mode 100644
index cbacc46..0000000
--- a/sublimelint/sublimelint/modules/python.py
+++ /dev/null
@@ -1,888 +0,0 @@
-# python.py - Lint checking for Python - given filename and contents of the code:
-# It provides a list of line numbers to outline and offsets to highlight.
-#
-# This specific module is a derivative of PyFlakes and part of the SublimeLint project.
-# SublimeLint is (c) 2011 Ryan Hileman and licensed under the MIT license.
-# URL: http://bochs.info/
-#
-# The original copyright notices for this file/project follows:
-#
-# (c) 2005-2008 Divmod, Inc.
-# See LICENSE file for details
-#
-# The LICENSE file is as follows:
-#
-# Copyright (c) 2005 Divmod, Inc., http://www.divmod.com/
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-# todo:
-# * fix regex for variable names inside strings (quotes)
-
-import sublime
-
-import __builtin__
-import os.path
-import compiler
-from compiler import ast
-
-class messages:
- class Message(object):
- message = ''
- message_args = ()
- def __init__(self, filename, lineno):
- self.filename = filename
- self.lineno = lineno
- def __str__(self):
- return self.message % self.message_args
-
-
- class UnusedImport(Message):
- message = '%r imported but unused'
- def __init__(self, filename, lineno, name):
- messages.Message.__init__(self, filename, lineno)
- self.name = name
- self.message_args = (name,)
-
-
- class RedefinedWhileUnused(Message):
- message = 'redefinition of unused %r from line %r'
- def __init__(self, filename, lineno, name, orig_lineno):
- messages.Message.__init__(self, filename, lineno)
- self.name = name
- self.orig_lineno = orig_lineno
- self.message_args = (name, orig_lineno)
-
-
- class ImportShadowedByLoopVar(Message):
- message = 'import %r from line %r shadowed by loop variable'
- def __init__(self, filename, lineno, name, orig_lineno):
- messages.Message.__init__(self, filename, lineno)
- self.name = name
- self.orig_lineno = orig_lineno
- self.message_args = (name, orig_lineno)
-
-
- class ImportStarUsed(Message):
- message = "'from %s import *' used; unable to detect undefined names"
- def __init__(self, filename, lineno, modname):
- messages.Message.__init__(self, filename, lineno)
- self.modname = modname
- self.message_args = (modname,)
-
-
- class UndefinedName(Message):
- message = 'undefined name %r'
- def __init__(self, filename, lineno, name):
- messages.Message.__init__(self, filename, lineno)
- self.name = name
- self.message_args = (name,)
-
-
-
- class UndefinedExport(Message):
- message = 'undefined name %r in __all__'
- def __init__(self, filename, lineno, name):
- messages.Message.__init__(self, filename, lineno)
- self.name = name
- self.message_args = (name,)
-
-
-
- class UndefinedLocal(Message):
- message = "local variable %r (defined in enclosing scope on line %r) referenced before assignment"
- def __init__(self, filename, lineno, name, orig_lineno):
- messages.Message.__init__(self, filename, lineno)
- self.name = name
- self.orig_lineno = orig_lineno
- self.message_args = (name, orig_lineno)
-
-
- class DuplicateArgument(Message):
- message = 'duplicate argument %r in function definition'
- def __init__(self, filename, lineno, name):
- messages.Message.__init__(self, filename, lineno)
- self.name = name
- self.message_args = (name,)
-
-
- class RedefinedFunction(Message):
- message = 'redefinition of function %r from line %r'
- def __init__(self, filename, lineno, name, orig_lineno):
- messages.Message.__init__(self, filename, lineno)
- self.name = name
- self.orig_lineno = orig_lineno
- self.message_args = (name, orig_lineno)
-
-
- class LateFutureImport(Message):
- message = 'future import(s) %r after other statements'
- def __init__(self, filename, lineno, names):
- messages.Message.__init__(self, filename, lineno)
- self.names = names
- self.message_args = (names,)
-
-
- class UnusedVariable(Message):
- """
- Indicates that a variable has been explicity assigned to but not actually
- used.
- """
-
- message = 'local variable %r is assigned to but never used'
- def __init__(self, filename, lineno, name):
- messages.Message.__init__(self, filename, lineno)
- self.name = name
- self.message_args = (name,)
-
-class Binding(object):
- """
- Represents the binding of a value to a name.
-
- The checker uses this to keep track of which names have been bound and
- which names have not. See L{Assignment} for a special type of binding that
- is checked with stricter rules.
-
- @ivar used: pair of (L{Scope}, line-number) indicating the scope and
- line number that this binding was last used
- """
-
- def __init__(self, name, source):
- self.name = name
- self.source = source
- self.used = False
-
-
- def __str__(self):
- return self.name
-
-
- def __repr__(self):
- return '<%s object %r from line %r at 0x%x>' % (self.__class__.__name__,
- self.name,
- self.source.lineno,
- id(self))
-
-class UnBinding(Binding):
- '''Created by the 'del' operator.'''
-
-
-
-class Importation(Binding):
- """
- A binding created by an import statement.
-
- @ivar fullName: The complete name given to the import statement,
- possibly including multiple dotted components.
- @type fullName: C{str}
- """
- def __init__(self, name, source):
- self.fullName = name
- name = name.split('.')[0]
- super(Importation, self).__init__(name, source)
-
-
-
-class Argument(Binding):
- """
- Represents binding a name as an argument.
- """
-
-
-
-class Assignment(Binding):
- """
- Represents binding a name with an explicit assignment.
-
- The checker will raise warnings for any Assignment that isn't used. Also,
- the checker does not consider assignments in tuple/list unpacking to be
- Assignments, rather it treats them as simple Bindings.
- """
-
-
-
-class FunctionDefinition(Binding):
- pass
-
-
-
-class ExportBinding(Binding):
- """
- A binding created by an C{__all__} assignment. If the names in the list
- can be determined statically, they will be treated as names for export and
- additional checking applied to them.
-
- The only C{__all__} assignment that can be recognized is one which takes
- the value of a literal list containing literal strings. For example::
-
- __all__ = ["foo", "bar"]
-
- Names which are imported and not otherwise used but appear in the value of
- C{__all__} will not have an unused import warning reported for them.
- """
- def names(self):
- """
- Return a list of the names referenced by this binding.
- """
- names = []
- if isinstance(self.source, ast.List):
- for node in self.source.nodes:
- if isinstance(node, ast.Const):
- names.append(node.value)
- return names
-
-
-
-class Scope(dict):
- importStarred = False # set to True when import * is found
-
-
- def __repr__(self):
- return '<%s at 0x%x %s>' % (self.__class__.__name__, id(self), dict.__repr__(self))
-
-
- def __init__(self):
- super(Scope, self).__init__()
-
-
-
-class ClassScope(Scope):
- pass
-
-
-
-class FunctionScope(Scope):
- """
- I represent a name scope for a function.
-
- @ivar globals: Names declared 'global' in this function.
- """
- def __init__(self):
- super(FunctionScope, self).__init__()
- self.globals = {}
-
-
-
-class ModuleScope(Scope):
- pass
-
-
-# Globally defined names which are not attributes of the __builtin__ module.
-_MAGIC_GLOBALS = ['__file__', '__builtins__']
-
-
-
-class Checker(object):
- """
- I check the cleanliness and sanity of Python code.
-
- @ivar _deferredFunctions: Tracking list used by L{deferFunction}. Elements
- of the list are two-tuples. The first element is the callable passed
- to L{deferFunction}. The second element is a copy of the scope stack
- at the time L{deferFunction} was called.
-
- @ivar _deferredAssignments: Similar to C{_deferredFunctions}, but for
- callables which are deferred assignment checks.
- """
-
- nodeDepth = 0
- traceTree = False
-
- def __init__(self, tree, filename='(none)'):
- self._deferredFunctions = []
- self._deferredAssignments = []
- self.dead_scopes = []
- self.messages = []
- self.filename = filename
- self.scopeStack = [ModuleScope()]
- self.futuresAllowed = True
- self.handleChildren(tree)
- self._runDeferred(self._deferredFunctions)
- # Set _deferredFunctions to None so that deferFunction will fail
- # noisily if called after we've run through the deferred functions.
- self._deferredFunctions = None
- self._runDeferred(self._deferredAssignments)
- # Set _deferredAssignments to None so that deferAssignment will fail
- # noisly if called after we've run through the deferred assignments.
- self._deferredAssignments = None
- del self.scopeStack[1:]
- self.popScope()
- self.check_dead_scopes()
-
-
- def deferFunction(self, callable):
- '''
- Schedule a function handler to be called just before completion.
-
- This is used for handling function bodies, which must be deferred
- because code later in the file might modify the global scope. When
- `callable` is called, the scope at the time this is called will be
- restored, however it will contain any new bindings added to it.
- '''
- self._deferredFunctions.append((callable, self.scopeStack[:]))
-
-
- def deferAssignment(self, callable):
- """
- Schedule an assignment handler to be called just after deferred
- function handlers.
- """
- self._deferredAssignments.append((callable, self.scopeStack[:]))
-
-
- def _runDeferred(self, deferred):
- """
- Run the callables in C{deferred} using their associated scope stack.
- """
- for handler, scope in deferred:
- self.scopeStack = scope
- handler()
-
-
- def scope(self):
- return self.scopeStack[-1]
- scope = property(scope)
-
- def popScope(self):
- self.dead_scopes.append(self.scopeStack.pop())
-
-
- def check_dead_scopes(self):
- """
- Look at scopes which have been fully examined and report names in them
- which were imported but unused.
- """
- for scope in self.dead_scopes:
- export = isinstance(scope.get('__all__'), ExportBinding)
- if export:
- all = scope['__all__'].names()
- if os.path.split(self.filename)[1] != '__init__.py':
- # Look for possible mistakes in the export list
- undefined = set(all) - set(scope)
- for name in undefined:
- self.report(
- messages.UndefinedExport,
- scope['__all__'].source.lineno,
- name)
- else:
- all = []
-
- # Look for imported names that aren't used.
- for importation in scope.itervalues():
- if isinstance(importation, Importation):
- if not importation.used and importation.name not in all:
- self.report(
- messages.UnusedImport,
- importation.source.lineno,
- importation.name)
-
-
- def pushFunctionScope(self):
- self.scopeStack.append(FunctionScope())
-
- def pushClassScope(self):
- self.scopeStack.append(ClassScope())
-
- def report(self, messageClass, *args, **kwargs):
- self.messages.append(messageClass(self.filename, *args, **kwargs))
-
- def handleChildren(self, tree):
- for node in tree.getChildNodes():
- self.handleNode(node, tree)
-
- def handleNode(self, node, parent):
- node.parent = parent
- if self.traceTree:
- print ' ' * self.nodeDepth + node.__class__.__name__
- self.nodeDepth += 1
- nodeType = node.__class__.__name__.upper()
- if nodeType not in ('STMT', 'FROM'):
- self.futuresAllowed = False
- try:
- handler = getattr(self, nodeType)
- handler(node)
- finally:
- self.nodeDepth -= 1
- if self.traceTree:
- print ' ' * self.nodeDepth + 'end ' + node.__class__.__name__
-
- def ignore(self, node):
- pass
-
- STMT = PRINT = PRINTNL = TUPLE = LIST = ASSTUPLE = ASSATTR = \
- ASSLIST = GETATTR = SLICE = SLICEOBJ = IF = CALLFUNC = DISCARD = \
- RETURN = ADD = MOD = SUB = NOT = UNARYSUB = INVERT = ASSERT = COMPARE = \
- SUBSCRIPT = AND = OR = TRYEXCEPT = RAISE = YIELD = DICT = LEFTSHIFT = \
- RIGHTSHIFT = KEYWORD = TRYFINALLY = WHILE = EXEC = MUL = DIV = POWER = \
- FLOORDIV = BITAND = BITOR = BITXOR = LISTCOMPFOR = LISTCOMPIF = \
- AUGASSIGN = BACKQUOTE = UNARYADD = GENEXPR = GENEXPRFOR = GENEXPRIF = \
- IFEXP = handleChildren
-
- CONST = PASS = CONTINUE = BREAK = ELLIPSIS = ignore
-
- def addBinding(self, lineno, value, reportRedef=True):
- '''Called when a binding is altered.
-
- - `lineno` is the line of the statement responsible for the change
- - `value` is the optional new value, a Binding instance, associated
- with the binding; if None, the binding is deleted if it exists.
- - if `reportRedef` is True (default), rebinding while unused will be
- reported.
- '''
- if (isinstance(self.scope.get(value.name), FunctionDefinition)
- and isinstance(value, FunctionDefinition)):
- self.report(messages.RedefinedFunction,
- lineno, value.name, self.scope[value.name].source.lineno)
-
- if not isinstance(self.scope, ClassScope):
- for scope in self.scopeStack[::-1]:
- existing = scope.get(value.name)
- if (isinstance(existing, Importation)
- and not existing.used
- and (not isinstance(value, Importation) or value.fullName == existing.fullName)
- and reportRedef):
-
- self.report(messages.RedefinedWhileUnused,
- lineno, value.name, scope[value.name].source.lineno)
-
- if isinstance(value, UnBinding):
- try:
- del self.scope[value.name]
- except KeyError:
- self.report(messages.UndefinedName, lineno, value.name)
- else:
- self.scope[value.name] = value
-
-
- def WITH(self, node):
- """
- Handle C{with} by checking the target of the statement (which can be an
- identifier, a list or tuple of targets, an attribute, etc) for
- undefined names and defining any it adds to the scope and by continuing
- to process the suite within the statement.
- """
- # Check the "foo" part of a "with foo as bar" statement. Do this no
- # matter what, since there's always a "foo" part.
- self.handleNode(node.expr, node)
-
- if node.vars is not None:
- self.handleNode(node.vars, node)
-
- self.handleChildren(node.body)
-
-
- def GLOBAL(self, node):
- """
- Keep track of globals declarations.
- """
- if isinstance(self.scope, FunctionScope):
- self.scope.globals.update(dict.fromkeys(node.names))
-
- def LISTCOMP(self, node):
- for qual in node.quals:
- self.handleNode(qual, node)
- self.handleNode(node.expr, node)
-
- GENEXPRINNER = LISTCOMP
-
- def FOR(self, node):
- """
- Process bindings for loop variables.
- """
- vars = []
- def collectLoopVars(n):
- if hasattr(n, 'name'):
- vars.append(n.name)
- else:
- for c in n.getChildNodes():
- collectLoopVars(c)
-
- collectLoopVars(node.assign)
- for varn in vars:
- if (isinstance(self.scope.get(varn), Importation)
- # unused ones will get an unused import warning
- and self.scope[varn].used):
- self.report(messages.ImportShadowedByLoopVar,
- node.lineno, varn, self.scope[varn].source.lineno)
-
- self.handleChildren(node)
-
- def NAME(self, node):
- """
- Locate the name in locals / function / globals scopes.
- """
- # try local scope
- importStarred = self.scope.importStarred
- try:
- self.scope[node.name].used = (self.scope, node.lineno)
- except KeyError:
- pass
- else:
- return
-
- # try enclosing function scopes
-
- for scope in self.scopeStack[-2:0:-1]:
- importStarred = importStarred or scope.importStarred
- if not isinstance(scope, FunctionScope):
- continue
- try:
- scope[node.name].used = (self.scope, node.lineno)
- except KeyError:
- pass
- else:
- return
-
- # try global scope
-
- importStarred = importStarred or self.scopeStack[0].importStarred
- try:
- self.scopeStack[0][node.name].used = (self.scope, node.lineno)
- except KeyError:
- if ((not hasattr(__builtin__, node.name))
- and node.name not in _MAGIC_GLOBALS
- and not importStarred):
- if (os.path.basename(self.filename) == '__init__.py' and
- node.name == '__path__'):
- # the special name __path__ is valid only in packages
- pass
- else:
- self.report(messages.UndefinedName, node.lineno, node.name)
-
-
- def FUNCTION(self, node):
- if getattr(node, "decorators", None) is not None:
- self.handleChildren(node.decorators)
- self.addBinding(node.lineno, FunctionDefinition(node.name, node))
- self.LAMBDA(node)
-
- def LAMBDA(self, node):
- for default in node.defaults:
- self.handleNode(default, node)
-
- def runFunction():
- args = []
-
- def addArgs(arglist):
- for arg in arglist:
- if isinstance(arg, tuple):
- addArgs(arg)
- else:
- if arg in args:
- self.report(messages.DuplicateArgument, node.lineno, arg)
- args.append(arg)
-
- self.pushFunctionScope()
- addArgs(node.argnames)
- for name in args:
- self.addBinding(node.lineno, Argument(name, node), reportRedef=False)
- self.handleNode(node.code, node)
- def checkUnusedAssignments():
- """
- Check to see if any assignments have not been used.
- """
- for name, binding in self.scope.iteritems():
- if (not binding.used and not name in self.scope.globals
- and isinstance(binding, Assignment)):
- self.report(messages.UnusedVariable,
- binding.source.lineno, name)
- self.deferAssignment(checkUnusedAssignments)
- self.popScope()
-
- self.deferFunction(runFunction)
-
-
- def CLASS(self, node):
- """
- Check names used in a class definition, including its decorators, base
- classes, and the body of its definition. Additionally, add its name to
- the current scope.
- """
- if getattr(node, "decorators", None) is not None:
- self.handleChildren(node.decorators)
- for baseNode in node.bases:
- self.handleNode(baseNode, node)
- self.addBinding(node.lineno, Binding(node.name, node))
- self.pushClassScope()
- self.handleChildren(node.code)
- self.popScope()
-
-
- def ASSNAME(self, node):
- if node.flags == 'OP_DELETE':
- if isinstance(self.scope, FunctionScope) and node.name in self.scope.globals:
- del self.scope.globals[node.name]
- else:
- self.addBinding(node.lineno, UnBinding(node.name, node))
- else:
- # if the name hasn't already been defined in the current scope
- if isinstance(self.scope, FunctionScope) and node.name not in self.scope:
- # for each function or module scope above us
- for scope in self.scopeStack[:-1]:
- if not isinstance(scope, (FunctionScope, ModuleScope)):
- continue
- # if the name was defined in that scope, and the name has
- # been accessed already in the current scope, and hasn't
- # been declared global
- if (node.name in scope
- and scope[node.name].used
- and scope[node.name].used[0] is self.scope
- and node.name not in self.scope.globals):
- # then it's probably a mistake
- self.report(messages.UndefinedLocal,
- scope[node.name].used[1],
- node.name,
- scope[node.name].source.lineno)
- break
-
- if isinstance(node.parent,
- (ast.For, ast.ListCompFor, ast.GenExprFor,
- ast.AssTuple, ast.AssList)):
- binding = Binding(node.name, node)
- elif (node.name == '__all__' and
- isinstance(self.scope, ModuleScope) and
- isinstance(node.parent, ast.Assign)):
- binding = ExportBinding(node.name, node.parent.expr)
- else:
- binding = Assignment(node.name, node)
- if node.name in self.scope:
- binding.used = self.scope[node.name].used
- self.addBinding(node.lineno, binding)
-
- def ASSIGN(self, node):
- self.handleNode(node.expr, node)
- for subnode in node.nodes[::-1]:
- self.handleNode(subnode, node)
-
- def IMPORT(self, node):
- for name, alias in node.names:
- name = alias or name
- importation = Importation(name, node)
- self.addBinding(node.lineno, importation)
-
- def FROM(self, node):
- if node.modname == '__future__':
- if not self.futuresAllowed:
- self.report(messages.LateFutureImport, node.lineno, [n[0] for n in node.names])
- else:
- self.futuresAllowed = False
-
- for name, alias in node.names:
- if name == '*':
- self.scope.importStarred = True
- self.report(messages.ImportStarUsed, node.lineno, node.modname)
- continue
- name = alias or name
- importation = Importation(name, node)
- if node.modname == '__future__':
- importation.used = (self.scope, node.lineno)
- self.addBinding(node.lineno, importation)
-
-class OffsetError(messages.Message):
- message = '%r at offset %r'
- def __init__(self, filename, lineno, text, offset):
- messages.Message.__init__(self, filename, lineno)
- self.offset = offset
- self.message_args = (text, offset)
-
-class PythonError(messages.Message):
- message = '%r'
- def __init__(self, filename, lineno, text):
- messages.Message.__init__(self, filename, lineno)
- self.message_args = (text,)
-
-def check(codeString, filename):
- codeString = codeString.rstrip()
- try:
- try:
- compile(codeString, filename, "exec")
- except MemoryError:
- # Python 2.4 will raise MemoryError if the source can't be
- # decoded.
- if sys.version_info[:2] == (2, 4):
- raise SyntaxError(None)
- raise
- except (SyntaxError, IndentationError), value:
- # print traceback.format_exc() # helps debug new cases
- msg = value.args[0]
-
- lineno, offset, text = value.lineno, value.offset, value.text
-
- # If there's an encoding problem with the file, the text is None.
- if text is None:
- # Avoid using msg, since for the only known case, it contains a
- # bogus message that claims the encoding the file declared was
- # unknown.
- if msg.startswith('duplicate argument'):
- arg = msg.split('duplicate argument ',1)[1].split(' ',1)[0].strip('\'"')
- error = messages.DuplicateArgument(filename, lineno, arg)
- else:
- error = PythonError(filename, lineno, msg)
- else:
- line = text.splitlines()[-1]
-
- if offset is not None:
- offset = offset - (len(text) - len(line))
-
- if offset is not None:
- error = OffsetError(filename, lineno, msg, offset)
- else:
- error = PythonError(filename, lineno, msg)
-
- return [error]
- except ValueError, e:
- return [PythonError(filename, 0, e.args[0])]
- else:
- # Okay, it's syntactically valid. Now parse it into an ast and check
- # it.
- tree = compiler.parse(codeString)
- w = Checker(tree, filename)
- w.messages.sort(lambda a, b: cmp(a.lineno, b.lineno))
- return w.messages
-
-# end pyflakes
-# start sublimelint python plugin
-
-import sys, re
-__all__ = ['run', 'language']
-language = 'Python'
-
-def run(code, view, filename='untitled'):
- stripped_lines = []
- good_lines = []
- lines = code.split('\n')
- for i in xrange(len(lines)):
- line = lines[i]
- if not line.strip() or line.strip().startswith('#'):
- stripped_lines.append(i)
- else:
- good_lines.append(line)
-
- text = '\n'.join(good_lines)
- errors = check(text, filename)
-
- lines = set()
- underline = []
-
- def underlineRange(lineno, position, length=1):
- line = view.full_line(view.text_point(lineno, 0))
- position += line.begin()
-
- for i in xrange(length):
- underline.append(sublime.Region(position + i))
-
- def underlineRegex(lineno, regex, wordmatch=None, linematch=None):
- lines.add(lineno)
- offset = 0
-
- line = view.full_line(view.text_point(lineno, 0))
- lineText = view.substr(line)
- if linematch:
- match = re.match(linematch, lineText)
- if match:
- lineText = match.group('match')
- offset = match.start('match')
- else:
- return
-
- iters = re.finditer(regex, lineText)
- results = [(result.start('underline'), result.end('underline')) for result in iters if
- not wordmatch or result.group('underline') == wordmatch]
-
- for start, end in results:
- underlineRange(lineno, start+offset, end-start)
-
- def underlineWord(lineno, word):
- regex = r'((and|or|not|if|elif|while|in)\s+|[+\-*^%%<>=\(\{])*\s*(?P[\w\.]*%s[\w]*)' % (word)
- underlineRegex(lineno, regex, word)
-
- def underlineImport(lineno, word):
- linematch = '(from\s+[\w_\.]+\s+)?import\s+(?P[^#;]+)'
- regex = '(^|\s+|,\s*|as\s+)(?P[\w]*%s[\w]*)' % word
- underlineRegex(lineno, regex, word, linematch)
-
- def underlineForVar(lineno, word):
- regex = 'for\s+(?P[\w]*%s[\w*])' % word
- underlineRegex(lineno, regex, word)
-
- def underlineDuplicateArgument(lineno, word):
- regex = 'def [\w_]+\(.*?(?P[\w]*%s[\w]*)' % word
- underlineRegex(lineno, regex, word)
-
- errorMessages = {}
- def addMessage(lineno, message):
- message = str(message)
- if lineno in errorMessages:
- errorMessages[lineno].append(message)
- else:
- errorMessages[lineno] = [message]
-
- for error in errors:
- error.lineno -= 1
- for i in stripped_lines:
- if error.lineno >= i:
- error.lineno += 1
-
- lines.add(error.lineno)
- addMessage(error.lineno, error)
- if isinstance(error, OffsetError):
- underlineRange(error.lineno, error.offset)
-
- elif isinstance(error, PythonError):
- pass
-
- elif isinstance(error, messages.UnusedImport):
- underlineImport(error.lineno, error.name)
-
- elif isinstance(error, messages.RedefinedWhileUnused):
- underlineWord(error.lineno, error.name)
-
- elif isinstance(error, messages.ImportShadowedByLoopVar):
- underlineForVar(error.lineno, error.name)
-
- elif isinstance(error, messages.ImportStarUsed):
- underlineImport(error.lineno, '\*')
-
- elif isinstance(error, messages.UndefinedName):
- underlineWord(error.lineno, error.name)
-
- elif isinstance(error, messages.UndefinedExport):
- underlineWord(error.lineno, error.name)
-
- elif isinstance(error, messages.UndefinedLocal):
- underlineWord(error.lineno, error.name)
-
- elif isinstance(error, messages.DuplicateArgument):
- underlineDuplicateArgument(error.lineno, error.name)
-
- elif isinstance(error, messages.RedefinedFunction):
- underlineWord(error.lineno, error.name)
-
- elif isinstance(error, messages.LateFutureImport):
- pass
-
- elif isinstance(error, messages.UnusedVariable):
- underlineWord(error.lineno, error.name)
-
- else:
- print 'Oops, we missed an error type!'
-
- return underline, lines, errorMessages, True
diff --git a/sublimelint/sublimelint/modules/ruby.py b/sublimelint/sublimelint/modules/ruby.py
deleted file mode 100644
index d60297b..0000000
--- a/sublimelint/sublimelint/modules/ruby.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# ruby.py - sublimelint package for checking ruby files
-
-import subprocess, os
-
-def check(codeString, filename):
- info = None
- if os.name == 'nt':
- info = subprocess.STARTUPINFO()
- info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
- info.wShowWindow = subprocess.SW_HIDE
-
- process = subprocess.Popen(('ruby', '-wc'),
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- startupinfo=info)
- result = process.communicate(codeString)[0]
-
- return result
-
-# start sublimelint Ruby plugin
-import re
-__all__ = ['run', 'language']
-language = 'Ruby'
-description =\
-'''* view.run_command("lint", "Ruby")
- Turns background linter off and runs the default Ruby linter
- (ruby -c, assumed to be on $PATH) on current view.
-'''
-
-def run(code, view, filename='untitled'):
- errors = check(code, filename)
-
- lines = set()
- underline = [] # leave this here for compatibility with original plugin
-
- errorMessages = {}
- def addMessage(lineno, message):
- message = str(message)
- if lineno in errorMessages:
- errorMessages[lineno].append(message)
- else:
- errorMessages[lineno] = [message]
-
- for line in errors.splitlines():
- match = re.match(r'^.+:(?P\d+):\s+(?P.+)', line)
-
- if match:
- error, line = match.group('error'), match.group('line')
-
- lineno = int(line) - 1
- lines.add(lineno)
- addMessage(lineno, error)
-
- return underline, lines, errorMessages, True
diff --git a/sublimelint/sublimelint_plugin.py b/sublimelint/sublimelint_plugin.py
deleted file mode 100644
index 4438135..0000000
--- a/sublimelint/sublimelint_plugin.py
+++ /dev/null
@@ -1,191 +0,0 @@
-import sublime, sublime_plugin
-import os, sys, glob
-
-## todo:
-# * fix lag (was partially caused by multiple worker threads - evaluate if it's still an issue)
-
-## language module loading
-
-# mapping of language name to language module
-languages = {}
-
-# import config
-basepath = 'sublimelint/modules'
-modpath = basepath.replace('/', '.')
-ignore = '__init__',
-basedir = os.getcwd()
-
-def load_module(name):
- fullmod = '%s.%s' % (modpath, name)
-
- # make sure the path didn't change on us (this is needed for submodule reload)
- pushd = os.getcwd()
- os.chdir(basedir)
-
- __import__(fullmod)
-
- # this following line does two things:
- # first, we get the actual module from sys.modules, not the base mod returned by __import__
- # second, we get an updated version with reload() so module development is easier
- # (save sublimelint_plugin.py to make sublime text reload language submodules)
- mod = sys.modules[fullmod] = reload(sys.modules[fullmod])
-
- # update module's __file__ to absolute path so we can reload it if saved with sublime text
- mod.__file__ = os.path.abspath(mod.__file__).rstrip('co')
-
- try:
- language = mod.language
- languages[language] = mod
- except AttributeError:
- print 'SublimeLint: Error loading %s - no language specified' % modf
- except:
- print 'SublimeLint: General error importing %s' % modf
-
- os.chdir(pushd)
-
-def reload_module(module):
- fullmod = module.__name__
- if not fullmod.startswith(modpath):
- return
-
- name = fullmod.replace(modpath+'.', '', 1)
- load_module(name)
-
-for modf in glob.glob('%s/*.py' % basepath):
- base, name = os.path.split(modf)
- name = name.split('.', 1)[0]
- if name in ignore: continue
-
- load_module(name)
-
-## bulk of the code
-
-# TODO: check to see if the types specified after drawType in the codestill work and replace as necessary
-drawType = 4 | 32 # from before ST2 had sublime.DRAW_*
-
-global lineMessages
-lineMessages = {}
-
-def run(module, view):
- global lineMessages
- vid = view.id()
-
- text = view.substr(sublime.Region(0, view.size())).encode('utf-8')
-
- if view.file_name():
- filename = os.path.split(view.file_name())[-1]
- else:
- filename = 'untitled'
-
- underline, lines, errorMessages, clearOutlines = module.run(text, view, filename)
- lineMessages[vid] = errorMessages
-
- view.erase_regions('lint-syntax')
- view.erase_regions('lint-syntax-underline')
- view.erase_regions('lint-underline')
-
- if clearOutlines:
- view.erase_regions('lint-outlines')
-
- if underline:
- view.add_regions('lint-underline', underline, 'keyword', drawType)#sublime.DRAW_EMPTY_AS_OVERWRITE | sublime.DRAW_OUTLINED)
-
- if lines:
- outlines = [view.full_line(view.text_point(lineno, 0)) for lineno in lines]
- view.add_regions('lint-outlines', outlines, 'keyword', drawType)#sublime.DRAW_EMPTY_AS_OVERWRITE | sublime.DRAW_OUTLINED)
-
-
-def validate(view):
- for language in languages:
- if language in view.settings().get("syntax"):
- run(languages[language], view)
- break
-
-import time, thread
-queue = {}
-lookup = {}
-
-def validate_runner(): # this threaded runner keeps it from slowing down UI while you type
- while True:
- time.sleep(0.5)
- for vid in dict(queue):
- if queue[vid] == 0:
- v = lookup[vid]
- def _view():
- try:
- validate(v)
- except RuntimeError, excp:
- print excp
- sublime.set_timeout(_view, 100)
- try: del queue[vid]
- except: pass
- try: del lookup[vid]
- except: pass
- else:
- queue[vid] = 0
-
-def validate_hit(view):
- for language in languages:
- if language in view.settings().get("syntax"):
- break
- else:
- view.erase_regions('lint-syntax')
- view.erase_regions('lint-syntax-underline')
- view.erase_regions('lint-underline')
- view.erase_regions('lint-outlines')
- return
-
- vid = view.id()
- lookup[vid] = view
- queue[vid] = 1
-
-# only start the thread once - otherwise the plugin will get laggy when saving it often
-if not 'already' in globals():
- already = True
- thread.start_new_thread(validate_runner, ())
-
-class pyflakes(sublime_plugin.EventListener):
- def __init__(self, *args, **kwargs):
- sublime_plugin.EventListener.__init__(self, *args, **kwargs)
- self.lastCount = {}
-
- def on_modified(self, view):
- validate_hit(view)
- return
-
- # alternate method which works alright when we don't have threads/set_timeout
- # from when I ported to early X beta :P
- text = view.substr(sublime.Region(0, view.size())).encode('utf-8')
- count = text.count('\n')
- if count > 500: return
- bid = view.buffer_id()
-
- if bid in self.lastCount:
- if self.lastCount[bid] != count:
- validate(view)
-
- self.lastCount[bid] = count
-
- def on_load(self, view):
- validate(view)
-
- def on_post_save(self, view):
- # this will reload submodules if they are saved with sublime text
- for name, module in languages.items():
- if module.__file__ == view.file_name():
- print 'Sublime Lint - Reloading language:', module.language
- reload_module(module)
- break
-
- validate_hit(view)
-
- def on_selection_modified(self, view):
- vid = view.id()
- lineno = view.rowcol(view.sel()[0].end())[0]
- if vid in lineMessages and lineno in lineMessages[vid]:
- try: # workaround for issue #18
- view.set_status('pyflakes', '; '.join(lineMessages[vid][lineno]))
- except:
- view.erase_status('pyflakes')
- else:
- view.erase_status('pyflakes')