File: lexers.py

package info (click to toggle)
python-argcomplete 3.6.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 704 kB
  • sloc: python: 2,814; makefile: 50; sh: 7
file content (57 lines) | stat: -rw-r--r-- 2,131 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import os

from .exceptions import ArgcompleteException
from .io import debug
from .packages import _shlex


def split_line(line, point=None):
    if point is None:
        point = len(line)
    line = line[:point]
    lexer = _shlex.shlex(line, posix=True)
    lexer.whitespace_split = True
    lexer.wordbreaks = os.environ.get("_ARGCOMPLETE_COMP_WORDBREAKS", "")
    words = []

    def split_word(word):
        # TODO: make this less ugly
        point_in_word = len(word) + point - lexer.instream.tell()
        if isinstance(lexer.state, (str, bytes)) and lexer.state in lexer.whitespace:
            point_in_word += 1
        if point_in_word > len(word):
            debug("In trailing whitespace")
            words.append(word)
            word = ""
        prefix, suffix = word[:point_in_word], word[point_in_word:]
        prequote = ""
        # posix
        if lexer.state is not None and lexer.state in lexer.quotes:
            prequote = lexer.state
        # non-posix
        # if len(prefix) > 0 and prefix[0] in lexer.quotes:
        #    prequote, prefix = prefix[0], prefix[1:]

        return prequote, prefix, suffix, words, lexer.last_wordbreak_pos

    while True:
        try:
            word = lexer.get_token()
            if word == lexer.eof:
                # TODO: check if this is ever unsafe
                # raise ArgcompleteException("Unexpected end of input")
                return "", "", "", words, None
            if lexer.instream.tell() >= point:
                debug("word", word, "split, lexer state: '{s}'".format(s=lexer.state))
                return split_word(word)
            words.append(word)
        except ValueError:
            debug("word", lexer.token, "split (lexer stopped, state: '{s}')".format(s=lexer.state))
            if lexer.instream.tell() >= point:
                return split_word(lexer.token)
            else:
                msg = (
                    "Unexpected internal state. "
                    "Please report this bug at https://github.com/kislyuk/argcomplete/issues."
                )
                raise ArgcompleteException(msg)