"""Completers for pip."""
# pylint: disable=invalid-name, missing-docstring, unsupported-membership-test
# pylint: disable=unused-argument, not-an-iterable
import re
import subprocess

import xonsh.lazyasd as xl


@xl.lazyobject
def PIP_RE():
    return re.compile(r"\bx?pip(?:\d|\.)*")


@xl.lazyobject
def PIP_LIST_RE():
    return re.compile(r"\bx?pip(?:\d|\.)* (?:uninstall|show)")


@xl.lazyobject
def ALL_COMMANDS():
    try:
        help_text = str(
            subprocess.check_output(["pip", "--help"], stderr=subprocess.DEVNULL)
        )
    except FileNotFoundError:
        return []
    commands = re.findall(r"  (\w+)  ", help_text)
    return [c for c in commands if c not in ["completion", "help"]]


def complete_pip(prefix, line, begidx, endidx, ctx):
    """Completes python's package manager pip"""
    line_len = len(line.split())
    if (
        (line_len > 3)
        or (line_len > 2 and line.endswith(" "))
        or (not PIP_RE.search(line))
    ):
        return
    if PIP_LIST_RE.search(line):
        try:
            items = subprocess.check_output(["pip", "list"], stderr=subprocess.DEVNULL)
        except FileNotFoundError:
            return set()
        items = items.decode("utf-8").splitlines()
        return set(i.split()[0] for i in items if i.split()[0].startswith(prefix))

    if (line_len > 1 and line.endswith(" ")) or line_len > 2:
        # "pip show " -> no complete (note space)
        return
    if prefix not in ALL_COMMANDS:
        suggestions = [c for c in ALL_COMMANDS if c.startswith(prefix)]
        if suggestions:
            return suggestions, len(prefix)
    return ALL_COMMANDS, len(prefix)

xonsh/completers/pip.py
"""Completers for pip."""
# pylint: disable=invalid-name, missing-docstring, unsupported-membership-test
# pylint: disable=unused-argument, not-an-iterable
import re
import subprocess

import xonsh.lazyasd as xl


@xl.lazyobject
def PIP_RE():
    return re.compile(r"\bx?pip(?:\d|\.)*\b")


@xl.lazyobject
def PIP_LIST_RE():
    return re.compile(r"\bx?pip(?:\d|\.)*\b (?:uninstall|show)")


@xl.lazyobject
def ALL_COMMANDS():
    try:
        help_text = str(
            subprocess.check_output(["pip", "--help"], stderr=subprocess.DEVNULL)
        )
    except FileNotFoundError:
        return []
    commands = re.findall(r"  (\w+)  ", help_text)
    return [c for c in commands if c not in ["completion", "help"]]


def complete_pip(prefix, line, begidx, endidx, ctx):
    """Completes python's package manager pip"""
    line_len = len(line.split())
    if (
        (line_len > 3)
        or (line_len > 2 and line.endswith(" "))
        or (not PIP_RE.search(line))
    ):
        return
    if PIP_LIST_RE.search(line):
        try:
            items = subprocess.check_output(["pip", "list"], stderr=subprocess.DEVNULL)
        except FileNotFoundError:
            return set()
        items = items.decode("utf-8").splitlines()
        return set(i.split()[0] for i in items if i.split()[0].startswith(prefix))

    if (line_len > 1 and line.endswith(" ")) or line_len > 2:
        # "pip show " -> no complete (note space)
        return
    if prefix not in ALL_COMMANDS:
        suggestions = [c for c in ALL_COMMANDS if c.startswith(prefix)]
        if suggestions:
            return suggestions, len(prefix)
    return ALL_COMMANDS, len(prefix)

xonsh/completers/pip.py
diff --git a/news/fix_pip_completer.rst b/news/fix_pip_completer.rst
new file mode 100644
index 0000000000..7d38bbb9c6
--- /dev/null
+++ b/news/fix_pip_completer.rst
@@ -0,0 +1,23 @@
+**Added:**
+
+* <news item>
+
+**Changed:**
+
+* <news item>
+
+**Deprecated:**
+
+* <news item>
+
+**Removed:**
+
+* <news item>
+
+**Fixed:**
+
+* ``pip`` completer no longer erroneously fires for ``pipx``
+
+**Security:**
+
+* <news item>
diff --git a/tests/completers/test_pip_completer.py b/tests/completers/test_pip_completer.py
index 506464ab85..209913465d 100644
--- a/tests/completers/test_pip_completer.py
+++ b/tests/completers/test_pip_completer.py
@@ -33,6 +33,9 @@ def test_pip_list_re(line):
         "![thewholepipandpaboodle uninstall",
         "$[littlebopip show",
         "!(boxpip uninstall",
+        "pipx",
+        "vim pip_",
+        "pip_",
     ],
 )
 def test_pip_list_re(line):
diff --git a/xonsh/completers/pip.py b/xonsh/completers/pip.py
index 179689eeee..25b96bcb92 100644
--- a/xonsh/completers/pip.py
+++ b/xonsh/completers/pip.py
@@ -9,12 +9,12 @@
 
 @xl.lazyobject
 def PIP_RE():
-    return re.compile(r"\bx?pip(?:\d|\.)*")
+    return re.compile(r"\bx?pip(?:\d|\.)*\b")
 
 
 @xl.lazyobject
 def PIP_LIST_RE():
-    return re.compile(r"\bx?pip(?:\d|\.)* (?:uninstall|show)")
+    return re.compile(r"\bx?pip(?:\d|\.)*\b (?:uninstall|show)")
 
 
 @xl.lazyobject

Weird completion issue
<!--- Provide a general summary of the issue in the Title above -->
<!--- If you have a question along the lines of "How do I do this Bash command in xonsh"
please first look over the Bash to Xonsh translation guide: https://xon.sh/bash_to_xsh.html
If you don't find an answer there, please do open an issue! -->

## xonfig

<details>

```
$ xonfig
+------------------+-----------------+
| xonsh            | 0.9.12          |
| Python           | 3.7.4           |
| PLY              | 3.11            |
| have readline    | True            |
| prompt toolkit   | 2.0.9           |
| shell type       | prompt_toolkit2 |
| pygments         | 2.4.2           |
| on posix         | True            |
| on linux         | False           |
| on darwin        | True            |
| on windows       | False           |
| on cygwin        | False           |
| on msys2         | False           |
| is superuser     | False           |
| default encoding | utf-8           |
| xonsh encoding   | utf-8           |
| encoding errors  | surrogateescape |
+------------------+-----------------+
```

</details>

## Expected Behavior
<!--- Tell us what should happen -->
Tab completion behind shell command `vim` should work

## Current Behavior
<!--- Tell us what happens instead of the expected behavior -->
<!--- If part of your bug report is a traceback, please first enter debug mode before triggering the error
To enter debug mode, set the environment variable `XONSH_DEBUG=1` _before_ starting `xonsh`.
On Linux and OSX, an easy way to to do this is to run `env XONSH_DEBUG=1 xonsh` -->
existing file is not being found by completion (see screenshot).
As you can see in the lower part of the screenshot, the file `pip_packages_to_install.txt` exists in the current folder but isn't found when used behind the shell command `vim` (but does work behind `cat`).
Is this maybe created by interfering completions installed elsewhere? Maybe some vim completions from homebrew?


<img width="822" alt="Screenshot 2019-10-31 14 11 02" src="https://user-images.githubusercontent.com/69774/67982582-99090380-fbe8-11e9-839a-b6fd0536a3ed.png">
