Commit 32944049 authored by David Symonds's avatar David Symonds

misc/vim: fix :Import insertion heuristic.

If a factored import group has a blank line, assume it is dividing
separate groups of imports (e.g. standard library vs. site-specific).
        import (
                "bytes"
                "io"

                "mycorp/package"
        )

The most common case is inserting new standard library imports,
which are usually (stylistically) the first group, so we should drop
"net" in the above example immediately after "io".

Since this logic is getting non-trivial, add a test.

R=golang-dev, minux.ma, franciscossouza
CC=golang-dev
https://golang.org/cl/6445043
parent 4dc85d67
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
" in the current Go buffer, using proper style and ordering. " in the current Go buffer, using proper style and ordering.
" If {path} is already being imported, an error will be " If {path} is already being imported, an error will be
" displayed and the buffer will be untouched. " displayed and the buffer will be untouched.
" "
" :ImportAs {localname} {path} " :ImportAs {localname} {path}
" "
" Same as Import, but uses a custom local name for the package. " Same as Import, but uses a custom local name for the package.
...@@ -58,6 +58,12 @@ function! s:SwitchImport(enabled, localname, path) ...@@ -58,6 +58,12 @@ function! s:SwitchImport(enabled, localname, path)
return return
endif endif
" Extract any site prefix (e.g. github.com/).
" If other imports with the same prefix are grouped separately,
" we will add this new import with them.
" Only up to and including the first slash is used.
let siteprefix = matchstr(path, "^[^/]*/")
let qpath = '"' . path . '"' let qpath = '"' . path . '"'
if a:localname != '' if a:localname != ''
let qlocalpath = a:localname . ' ' . qpath let qlocalpath = a:localname . ' ' . qpath
...@@ -83,16 +89,31 @@ function! s:SwitchImport(enabled, localname, path) ...@@ -83,16 +89,31 @@ function! s:SwitchImport(enabled, localname, path)
let appendstr = qlocalpath let appendstr = qlocalpath
let indentstr = 1 let indentstr = 1
let appendline = line let appendline = line
let firstblank = -1
let lastprefix = ""
while line <= line("$") while line <= line("$")
let line = line + 1 let line = line + 1
let linestr = getline(line) let linestr = getline(line)
let m = matchlist(getline(line), '^\()\|\(\s\+\)\(\S*\s*\)"\(.\+\)"\)') let m = matchlist(getline(line), '^\()\|\(\s\+\)\(\S*\s*\)"\(.\+\)"\)')
if empty(m) if empty(m)
if siteprefix == ""
" must be in the first group
break
endif
" record this position, but keep looking
if firstblank < 0
let firstblank = line
endif
continue continue
endif endif
if m[1] == ')' if m[1] == ')'
" if there's no match, add it to the first group
if appendline < 0 && firstblank >= 0
let appendline = firstblank
endif
break break
endif endif
let lastprefix = matchstr(m[4], "^[^/]*/")
if a:localname != '' && m[3] != '' if a:localname != '' && m[3] != ''
let qlocalpath = printf('%-' . (len(m[3])-1) . 's %s', a:localname, qpath) let qlocalpath = printf('%-' . (len(m[3])-1) . 's %s', a:localname, qpath)
endif endif
...@@ -103,7 +124,16 @@ function! s:SwitchImport(enabled, localname, path) ...@@ -103,7 +124,16 @@ function! s:SwitchImport(enabled, localname, path)
let deleteline = line let deleteline = line
break break
elseif m[4] < path elseif m[4] < path
let appendline = line " don't set candidate position if we have a site prefix,
" we've passed a blank line, and this doesn't share the same
" site prefix.
if siteprefix == "" || firstblank < 0 || match(m[4], "^" . siteprefix) >= 0
let appendline = line
endif
elseif siteprefix != "" && match(m[4], "^" . siteprefix) >= 0
" first entry of site group
let appendline = line - 1
break
endif endif
endwhile endwhile
break break
......
#!/bin/bash -e
#
# Copyright 2012 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
#
# Tests for import.vim.
cd $(dirname $0)
cat > base.go <<EOF
package test
import (
"bytes"
"io"
"net"
"mycorp/foo"
)
EOF
fail=0
# usage: test_one new_import pattern
# Pattern is a PCRE expression that will match across lines.
test_one() {
echo 2>&1 -n "Import $1: "
vim -e -s -u /dev/null -U /dev/null --noplugin -c "source import.vim" \
-c "Import $1" -c 'wq! test.go' base.go
# ensure blank lines are treated correctly
if ! gofmt test.go | cmp test.go; then
echo 2>&1 "gofmt conflict"
gofmt test.go | diff -u test.go - | sed "s/^/\t/" 2>&1
fail=1
return
fi
if ! grep -P -q "(?s)$2" test.go; then
echo 2>&1 "$2 did not match"
cat test.go | sed "s/^/\t/" 2>&1
fail=1
return
fi
echo 2>&1 "ok"
}
test_one baz '"baz".*"bytes"'
test_one io/ioutil '"io".*"io/ioutil".*"net"'
test_one myc '"io".*"myc".*"net"' # prefix of a site prefix
test_one nat '"io".*"nat".*"net"'
test_one net/http '"net".*"net/http".*"mycorp/foo"'
test_one zoo '"net".*"zoo".*"mycorp/foo"'
test_one mycorp/bar '"net".*"mycorp/bar".*"mycorp/foo"'
test_one mycorp/goo '"net".*"mycorp/foo".*"mycorp/goo"'
rm -f base.go test.go
if [ $fail -gt 0 ]; then
echo 2>&1 "FAIL"
exit 1
fi
echo 2>&1 "PASS"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment