Permalink
Browse files

add erlang auto-indenter

  • Loading branch information...
1 parent b388f39 commit 1155cf8df2084b6558586757d838b1cefe50eb2e @ostinelli committed Sep 25, 2012
View
@@ -0,0 +1,17 @@
+# SublimErl Changelog
+
+### 0.4:
+ * added auto-indenting
+ * major code refactoring
+
+### 0.3:
+ * faster code completion (parser is now in python)
+ * code completion now adds parameter names
+ * support for complex project structure
+ * single tests now using rebar
+
+### 0.2:
+ * added code completion
+
+### 0.1:
+ * initial release, with integrated testing (eunit, CT and dialyzer)
View
@@ -19,6 +19,10 @@ Here's a screenshot of SublimErl's **Code Completion** feature:
![SublimErl screenshot](http://www.ostinelli.net/_out_images/code_completion_full.gif)
+Here's a screenshot of SublimErl's **Auto-Indenting** feature:
+
+![SublimErl screenshot](http://www.ostinelli.net/_out_images/sublimerl_indent.gif)
@nox

nox Oct 1, 2012

Contributor

Sorry, no posts matched your criteria.

+
Here's a screenshot of SublimErl **running an Eunit specific test** in file.
![SublimErl screenshot](http://www.ostinelli.net/_out_images/running_test.jpeg)
@@ -27,6 +31,7 @@ Usage
-----
* **Code Completion**: Just type and select available options
+* **Auto-Indenting**: hit `Command-Option-L` to auto-intent an entire file
* Run **single Eunit test**: position your cursor anywhere **within** your test function and hit `Command-Shift-F8`
* Run **all Eunit test** in file: position your cursor **outside** any test function and hit `Command-Shift-F8`
* Run **all Common Tests** in file: view the test file and hit `Command-Shift-F8`
@@ -2,5 +2,6 @@
{ "keys": ["ctrl+shift+f8"], "command": "sublim_erl_test", "context": [{ "key": "selector", "operator": "equal", "operand": "source.erlang" }] },
{ "keys": ["ctrl+shift+f9"], "command": "sublim_erl_dialyzer", "context": [{ "key": "selector", "operator": "equal", "operand": "source.erlang" }] },
{ "keys": ["ctrl+f8"], "command": "sublim_erl_redo" },
- { "keys": ["ctrl+alt+f8"], "command": "sublim_erl_ct_results" }
+ { "keys": ["ctrl+alt+f8"], "command": "sublim_erl_ct_results" },
+ { "keys": ["ctrl+alt+l"], "command": "sublim_erl_auto_format" }
]
@@ -2,5 +2,6 @@
{ "keys": ["super+shift+f8"], "command": "sublim_erl_test", "context": [{ "key": "selector", "operator": "equal", "operand": "source.erlang" }] },
{ "keys": ["super+shift+f9"], "command": "sublim_erl_dialyzer", "context": [{ "key": "selector", "operator": "equal", "operand": "source.erlang" }] },
{ "keys": ["super+f8"], "command": "sublim_erl_redo" },
- { "keys": ["super+alt+f8"], "command": "sublim_erl_ct_results" }
+ { "keys": ["super+alt+f8"], "command": "sublim_erl_ct_results" },
+ { "keys": ["super+alt+l"], "command": "sublim_erl_auto_format" }
]
@@ -1,38 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-%%! -smp enable debug verbose
-%% ==========================================================================================================
-%% SublimErl - A Sublime Text 2 Plugin for Erlang Integrated Testing & Code Completion
-%%
-%% Copyright (C) 2012, Roberto Ostinelli <roberto@ostinelli.net>.
-%% All rights reserved.
-%%
-%% BSD License
-%%
-%% Redistribution and use in source and binary forms, with or without modification, are permitted provided
-%% that the following conditions are met:
-%%
-%% * Redistributions of source code must retain the above copyright notice, this list of conditions and the
-%% following disclaimer.
-%% * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
-%% the following disclaimer in the documentation and/or other materials provided with the distribution.
-%% * Neither the name of the authors nor the names of its contributors may be used to endorse or promote
-%% products derived from this software without specific prior written permission.
-%%
-%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
-%% WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-%% PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-%% ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-%% TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-%% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-%% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-%% POSSIBILITY OF SUCH DAMAGE.
-%% ==========================================================================================================
--mode(compile).
-
-% command line exposure
-main(["lib_dir"]) ->
- io:format("~s", [code:lib_dir()]);
-
-main(_) ->
- halt(1).
View
@@ -30,9 +30,9 @@
SUBLIMERL_VERSION = '0.4-dev'
# imports
-import sublime, sublime_plugin
+import sublime
import os, subprocess, re, threading, webbrowser
-from sublimerl_core import SUBLIMERL, SublimErlProjectLoader
+from sublimerl_core import SUBLIMERL, SublimErlTextCommand, SublimErlProjectLoader
# test runner
@@ -168,7 +168,7 @@ def run(self):
def dialyzer_test(self, module_tests_name, filename):
# run dialyzer for file
- self.log("Running Dialyzer tests for \"%s\".\n" % filename)
+ self.log("Running Dialyzer tests for \"%s\".\n\n" % filename)
# compile eunit
self.compile_eunit_no_run()
# run dialyzer
@@ -376,27 +376,6 @@ def ct_or_eunit_test(self, view):
test_runner.start_test()
-# common text command class
-class SublimErlTextCommand(sublime_plugin.TextCommand):
- def run(self, edit):
- # run only if context matches
- if self._context_match(): return self.run_command(edit)
-
- def _context_match(self):
- # context matches if lang is source.erlang and if platfomr is not windows
- caret = self.view.sel()[0].a
- if 'source.erlang' in self.view.scope_name(caret) and sublime.platform() != 'windows': return True
- else: return False
-
- def is_enabled(self):
- # context menu
- if self._context_match(): return self.show_contextual_menu()
-
- def show_contextual_menu(self):
- # can be overridden
- return True
-
-
# dialyzer tests
class SublimErlDialyzerCommand(SublimErlTextCommand):
def run_command(self, edit):
View
@@ -27,7 +27,7 @@
# ==========================================================================================================
# imports
-import sublime
+import sublime, sublime_plugin
import os, subprocess, re
# plugin initialized (Sublime might need to be restarted if some env configs / preferences change)
@@ -39,6 +39,9 @@ def __init__(self):
self.init_error = None
self.plugin_path = None
+ self.completions_path = None
+ self.support_path = None
+
self.rebar_path = None
self.escript_path = None
self.dialyzer_path = None
@@ -50,6 +53,7 @@ def __init__(self):
self.env = None
self.settings = None
+
# initialize
self.set_settings()
self.set_env()
@@ -126,6 +130,7 @@ def test_path(path):
# paths
self.plugin_path = os.path.join(sublime.packages_path(), 'SublimErl')
self.completions_path = os.path.join(self.plugin_path, "completion")
+ self.support_path = os.path.join(self.plugin_path, "support")
return True
@@ -143,8 +148,8 @@ def get_exe_path(self, name):
return data
def set_erlang_libs_path(self):
- os.chdir(self.completions_path)
# run escript to get erlang lib path
+ os.chdir(self.support_path)
escript_command = "sublimerl_utility.erl lib_dir"
retcode, data = self.execute_os_command('%s %s' % (self.escript_path, escript_command))
self.erlang_libs_path = data
@@ -157,6 +162,10 @@ def execute_os_command(self, os_cmd):
return (p.returncode, stdout)
+ def shellquote(self, s):
+ return "'" + s.replace("'", "'\\''") + "'"
+
+
# initialize
SUBLIMERL = SublimErlGlobal()
@@ -243,13 +252,13 @@ def get_test_env(self):
env['PATH'] = "%s:%s:" % (env['PATH'], self.project_root)
return env
- def shellquote(self, s):
- return "'" + s.replace("'", "'\\''") + "'"
-
def compile_source(self):
# compile to ebin
retcode, data = self.execute_os_command('%s compile' % SUBLIMERL.rebar_path, dir_type='project', block=True, log=False)
+ def shellquote(self, s):
+ return SUBLIMERL.shellquote(s)
+
def execute_os_command(self, os_cmd, dir_type=None, block=False, log=True):
# set dir
if dir_type == 'project': os.chdir(self.project_root)
@@ -269,3 +278,24 @@ def execute_os_command(self, os_cmd, dir_type=None, block=False, log=True):
self.log(line)
stdout.append(line)
return (p.returncode, ''.join(stdout))
+
+
+# common text command class
+class SublimErlTextCommand(sublime_plugin.TextCommand):
+ def run(self, edit):
+ # run only if context matches
+ if self._context_match(): return self.run_command(edit)
+
+ def _context_match(self):
+ # context matches if lang is source.erlang and if platform is not windows
+ caret = self.view.sel()[0].a
+ if 'source.erlang' in self.view.scope_name(caret) and sublime.platform() != 'windows': return True
+ else: return False
+
+ def is_enabled(self):
+ # context menu
+ if self._context_match(): return self.show_contextual_menu()
+
+ def show_contextual_menu(self):
+ # can be overridden
+ return True
View
@@ -0,0 +1,70 @@
+# ==========================================================================================================
+# SublimErl - A Sublime Text 2 Plugin for Erlang Integrated Testing & Code Completion
+#
+# Copyright (C) 2012, Roberto Ostinelli <roberto@ostinelli.net>.
+# All rights reserved.
+#
+# BSD License
+#
+# Redistribution and use in source and binary forms, with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
+# the following disclaimer in the documentation and/or other materials provided with the distribution.
+# * Neither the name of the authors nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# ==========================================================================================================
+
+
+# imports
+import sublime, sublime_plugin, os, tempfile
+from sublimerl_core import SUBLIMERL, SublimErlTextCommand, SublimErlProjectLoader
+
+
+# main autoformat
+class SublimErlAutoFormat():
+
+ def __init__(self, view, edit):
+ self.view = view
+ self.edit = edit
+
+ def format(self):
+ # save current caret position
+ current_region = self.view.sel()[0]
+ # save current file contents to temp file
+ region_full = sublime.Region(0, self.view.size())
+ content = self.view.substr(region_full).encode('utf-8')
+ temp = tempfile.NamedTemporaryFile(delete=False)
+ temp.write(content)
+ temp.close()
+ # call erlang formatter
+ os.chdir(SUBLIMERL.support_path)
+ escript_command = "sublimerl_utility.erl format %s" % SUBLIMERL.shellquote(temp.name)
+ retcode, data = SUBLIMERL.execute_os_command('%s %s' % (SUBLIMERL.escript_path, escript_command))
+ # delete temp file
+ os.remove(temp.name)
+ if retcode == 0:
+ # substitute text
+ self.view.replace(self.edit, region_full, data.decode('utf-8'))
+ # reset caret to original position
+ self.view.sel().clear()
+ self.view.sel().add(current_region)
+ self.view.show(current_region)
+
+
+# repeat last test
+class SublimErlAutoFormatCommand(SublimErlTextCommand):
+ def run_command(self, edit):
+ formatter = SublimErlAutoFormat(self.view, edit)
+ formatter.format()
Oops, something went wrong.

0 comments on commit 1155cf8

Please sign in to comment.