summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Van Brunt <kmvanbrunt@gmail.com>2019-05-13 12:52:49 -0400
committerKevin Van Brunt <kmvanbrunt@gmail.com>2019-05-13 12:52:49 -0400
commitc4ee21446e1507ebd5c42a521fa2c0bcb2648c85 (patch)
tree8d209fc86254c727c9cdd502d58d9e0ec2331cd9
parent8ad8ddd10bf35f38e22b2c8f381faa4b2f87c853 (diff)
downloadcmd2-git-c4ee21446e1507ebd5c42a521fa2c0bcb2648c85.tar.gz
Preserving originally typed quotes of Statement.output_to for use in Statement.post_command()
-rw-r--r--cmd2/cmd2.py2
-rw-r--r--cmd2/parsing.py9
-rw-r--r--cmd2/utils.py37
3 files changed, 29 insertions, 19 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index d197e75e..c29a1812 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -2082,7 +2082,7 @@ class Cmd(cmd.Cmd):
if statement.output == constants.REDIRECTION_APPEND:
mode = 'a'
try:
- new_stdout = open(statement.output_to, mode)
+ new_stdout = open(utils.strip_quotes(statement.output_to), mode)
saved_state.redirecting = True
sys.stdout = self.stdout = new_stdout
except OSError as ex:
diff --git a/cmd2/parsing.py b/cmd2/parsing.py
index 067c9bf4..8febd270 100644
--- a/cmd2/parsing.py
+++ b/cmd2/parsing.py
@@ -2,7 +2,6 @@
# -*- coding: utf-8 -*-
"""Statement parsing classes for cmd2"""
-import os
import re
import shlex
from typing import Dict, Iterable, List, Optional, Tuple, Union
@@ -166,7 +165,7 @@ class Statement(str):
# if output was redirected, the redirection token, i.e. '>>'
output = attr.ib(default='', validator=attr.validators.instance_of(str))
- # if output was redirected, the destination file
+ # if output was redirected, the destination file token (quotes preserved)
output_to = attr.ib(default='', validator=attr.validators.instance_of(str))
def __new__(cls, value: object, *pos_args, **kw_args):
@@ -213,7 +212,7 @@ class Statement(str):
if self.output:
rtn += ' ' + self.output
if self.output_to:
- rtn += ' ' + utils.quote_string_if_needed(self.output_to)
+ rtn += ' ' + self.output_to
return rtn
@@ -495,9 +494,11 @@ class StatementParser:
output = constants.REDIRECTION_APPEND
output_index = append_index
+ # Check if we are redirecting to a file
if len(tokens) > output_index + 1:
unquoted_path = utils.strip_quotes(tokens[output_index + 1])
- output_to = os.path.expanduser(unquoted_path)
+ if unquoted_path:
+ output_to = utils.expand_user(tokens[output_index + 1])
# remove all the tokens after the output redirect
tokens = tokens[:output_index]
diff --git a/cmd2/utils.py b/cmd2/utils.py
index 398d39e6..54ad763d 100644
--- a/cmd2/utils.py
+++ b/cmd2/utils.py
@@ -275,25 +275,34 @@ def unquote_specific_tokens(args: List[str], tokens_to_unquote: List[str]) -> No
args[i] = unquoted_arg
+def expand_user(token: str) -> str:
+ """
+ Wrap os.expanduser() to support expanding ~ in quoted strings
+ :param token: the string to expand
+ """
+ if token:
+ if is_quoted(token):
+ quote_char = token[0]
+ token = strip_quotes(token)
+ else:
+ quote_char = ''
+
+ token = os.path.expanduser(token)
+
+ # Restore the quotes even if not needed to preserve what the user typed
+ if quote_char:
+ token = quote_char + token + quote_char
+
+ return token
+
+
def expand_user_in_tokens(tokens: List[str]) -> None:
"""
- Call os.path.expanduser() on all tokens in an already parsed list of command-line arguments.
- This also supports expanding user in quoted tokens.
+ Call expand_user() on all tokens in a list of strings
:param tokens: tokens to expand
"""
for index, _ in enumerate(tokens):
- if tokens[index]:
- # Check if the token is quoted. Since parsing already passed, there isn't
- # an unclosed quote. So we only need to check the first character.
- first_char = tokens[index][0]
- if first_char in constants.QUOTES:
- tokens[index] = strip_quotes(tokens[index])
-
- tokens[index] = os.path.expanduser(tokens[index])
-
- # Restore the quotes even if not needed to preserve what the user typed
- if first_char in constants.QUOTES:
- tokens[index] = first_char + tokens[index] + first_char
+ tokens[index] = expand_user(tokens[index])
def find_editor() -> str: