From 553488b391b95de78d519d9453744c1528426603 Mon Sep 17 00:00:00 2001 From: timesking Date: Sun, 11 Jan 2015 00:58:37 +0800 Subject: [PATCH] Try to make go imports work as separated cmd. goimports is useful tools, but if it is triggered in on-save, it is a little bit annoying when coding golang. So, I duplicate go_fmt with new go_imports, in order to give user a chance to set up below keybinding to run goimports mannually. So, the better user experience is , we set go_fmt while on-save, and use go_imports when we need it. ``` { "keys": ["super+.", "super+f"], "command": "gs_imports", "context": [{ "key": "selector", "operator": "equal", "operand": "source.go" }] }, ``` --- GoSublime.sublime-commands | 4 ++++ GoSublime.sublime-settings | 1 + gosubl/gs.py | 1 + gosubl/mg9.py | 22 ++++++++++++++++++++ gscommands.py | 31 ++++++++++++++++++++++++++++ src/gosubli.me/margo/m_goimports.go | 32 +++++++++++++++++++++++++++++ 6 files changed, 91 insertions(+) create mode 100644 src/gosubli.me/margo/m_goimports.go diff --git a/GoSublime.sublime-commands b/GoSublime.sublime-commands index 02a631f5..d64d0d88 100644 --- a/GoSublime.sublime-commands +++ b/GoSublime.sublime-commands @@ -65,6 +65,10 @@ "caption": "GoSublime: Fmt the current file (without saving it)", "command": "gs_fmt" }, + { + "caption": "GoSublime: Help you to make your imports clean", + "command": "gs_imports" + }, { "caption": "GoSublime: New Go File", "command": "gs_new_go_file" diff --git a/GoSublime.sublime-settings b/GoSublime.sublime-settings index 1238368a..bb9b40f6 100644 --- a/GoSublime.sublime-settings +++ b/GoSublime.sublime-settings @@ -45,6 +45,7 @@ // the command will be passed, to its stdin, the contents of the file // it must output the new file contents "fmt_cmd": [], + "goimports_cmd": ["goimports"], // Whether or not gslint is enabled "gslint_enabled": true, diff --git a/gosubl/gs.py b/gosubl/gs.py index f34bba86..62f08277 100644 --- a/gosubl/gs.py +++ b/gosubl/gs.py @@ -66,6 +66,7 @@ "fmt_tab_indent": True, "fmt_tab_width": 8, "fmt_cmd": [], + "goimports_cmd": ["goimports"], "gslint_enabled": False, "comp_lint_enabled": False, "comp_lint_commands": [], diff --git a/gosubl/mg9.py b/gosubl/mg9.py index fb751006..60254b55 100644 --- a/gosubl/mg9.py +++ b/gosubl/mg9.py @@ -320,6 +320,28 @@ def fmt(fn, src): }) return res.get('src', ''), err +def goimports(fn, src): + st = gs.settings_dict() + x = st.get('goimports_cmd') + if x: + res, err = bcall('sh', { + 'Env': sh.env(), + 'Cmd': { + 'Name': x[0], + 'Args': x[1:], + 'Input': src or '', + }, + }) + return res.get('out', ''), (err or res.get('err', '')) + + res, err = bcall('goimports', { + 'Fn': fn or '', + 'Src': src or '', + 'TabIndent': st.get('fmt_tab_indent'), + 'TabWidth': st.get('fmt_tab_width'), + }) + return res.get('src', ''), err + def import_paths(fn, src, f): tid = gs.begin(DOMAIN, 'Fetching import paths') def cb(res, err): diff --git a/gscommands.py b/gscommands.py index 0686d68d..29edb3d3 100644 --- a/gscommands.py +++ b/gscommands.py @@ -18,6 +18,36 @@ def run(self, edit): self.view.run_command("run_macro_file", {"file": "Packages/Default/Add Line.sublime-macro"}) self.view.run_command("toggle_comment", {"block": False}) +class GsImportsCommand(sublime_plugin.TextCommand): + def is_enabled(self): + fn = self.view.file_name() + if fn: + scope_ok = fn.lower().endswith('.go') + else: + scope_ok = gs.is_go_source_view(self.view) + + return scope_ok + + def run(self, edit): + vsize = self.view.size() + src = self.view.substr(sublime.Region(0, vsize)) + if not src.strip(): + return + + src, err = mg9.goimports(self.view.file_name(), src) + if err: + gs.println(DOMAIN, "cannot goimports file. error: `%s'" % err) + return + + if not src.strip(): + gs.println(DOMAIN, "cannot goimports file. it appears to be empty") + return + + _, err = gspatch.merge(self.view, vsize, src, edit) + if err: + msg = 'PANIC: Cannot goimports file. Check your source for errors (and maybe undo any changes).' + sublime.error_message("%s: %s: Merge failure: `%s'" % (DOMAIN, msg, err)) + class GsFmtCommand(sublime_plugin.TextCommand): def is_enabled(self): fn = self.view.file_name() @@ -64,6 +94,7 @@ def run(self, edit): self.view.run_command("gs_fmt") sublime.set_timeout(lambda: self.view.run_command("prompt_save_as"), 0) + class GsGotoRowColCommand(sublime_plugin.TextCommand): def run(self, edit, row, col=0): pt = self.view.text_point(row, col) diff --git a/src/gosubli.me/margo/m_goimports.go b/src/gosubli.me/margo/m_goimports.go new file mode 100644 index 00000000..680d9a8c --- /dev/null +++ b/src/gosubli.me/margo/m_goimports.go @@ -0,0 +1,32 @@ +package main + +import ( + "go/ast" + "go/parser" +) + +type mGoImports struct { + Fn string + Src string + TabIndent bool + TabWidth int +} + +func (m *mGoImports) Call() (interface{}, string) { + res := M{} + fset, af, err := parseAstFile(m.Fn, m.Src, parser.ParseComments) + if err == nil { + ast.SortImports(fset, af) + res["src"], err = printSrc(fset, af, m.TabIndent, m.TabWidth) + } + return res, errStr(err) +} + +func init() { + registry.Register("goimports", func(b *Broker) Caller { + return &mGoImports{ + TabIndent: true, + TabWidth: 8, + } + }) +}