Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix editor config when an argument with a space is used #953

Merged
merged 5 commits into from
May 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions features/core.feature
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ Feature: Basic reading and writing to a journal
When we open the editor and enter nothing
Then we should see the message "[Nothing saved to file]"

@skip_win
Scenario: Sending an argument with spaces to the editor should work
Given we use the config "editor-args.yaml"
When we open the editor and enter "lorem ipsum"
Then the editor should have been called with 5 arguments
And one editor argument should be "vim"
And one editor argument should be "-f"
And one editor argument should be "-c"
And one editor argument should match "'?setf markdown'?"

Scenario: Writing an empty entry from the command line
Given we use the config "basic.yaml"
When we run "jrnl" and enter nothing
Expand Down
12 changes: 12 additions & 0 deletions features/data/configs/editor-args.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
default_hour: 9
default_minute: 0
editor: vim -f -c 'setf markdown'
encrypt: false
highlight: true
journals:
default: features/journals/simple.journal
linewrap: 80
tagsymbols: "@"
template: false
timeformat: "%Y-%m-%d %H:%M"
indent_character: "|"
34 changes: 30 additions & 4 deletions features/steps/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from collections import defaultdict
import os
from pathlib import Path
import re
import shlex
import sys
import time
Expand Down Expand Up @@ -85,14 +86,37 @@ def open_editor_and_enter(context, text=""):
text = text or context.text or ""

def _mock_editor_function(command):
context.editor_command = command
tmpfile = command[-1]
with open(tmpfile, "w+") as f:
f.write(text)

return tmpfile

with patch("subprocess.call", side_effect=_mock_editor_function):
run(context, "jrnl")
context.execute_steps('when we run "jrnl"')


@then("the editor should have been called with {num} arguments")
def count_editor_args(context, num):
assert len(context.editor_command) == int(num)


@then('one editor argument should be "{arg}"')
def contains_editor_arg(context, arg):
args = context.editor_command
assert (
arg in args and args.count(arg) == 1
), f"\narg not in args exactly 1 time:\n{arg}\n{str(args)}"


@then('one editor argument should match "{regex}"')
def matches_editor_arg(context, regex):
args = context.editor_command
matches = list(filter(lambda x: re.match(regex, x), args))
assert (
len(matches) == 1
), f"\nRegex didn't match exactly 1 time:\n{regex}\n{str(args)}"


def _mock_getpass(inputs):
Expand Down Expand Up @@ -155,10 +179,12 @@ def run(context, command, cache_dir=None):
cache_dir = os.path.join("features", "cache", cache_dir)
command = command.format(cache_dir=cache_dir)

args = ushlex(command)[1:]
args = ushlex(command)

try:
cli.run(args or None)
context.exit_status = 0
with patch("sys.argv", args):
cli.run(args[1:])
context.exit_status = 0
except SystemExit as e:
context.exit_status = e.code

Expand Down
12 changes: 9 additions & 3 deletions jrnl/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,14 @@ def parse_args(args=None):
help="Opens an interactive interface for deleting entries.",
)

if not args:
args = []

# Handle '-123' as a shortcut for '-n 123'
num = re.compile(r"^-(\d+)$")
if args is None:
args = sys.argv[1:]
return parser.parse_args([num.sub(r"-n \1", a) for a in args])
args = [num.sub(r"-n \1", arg) for arg in args]

return parser.parse_args(args)


def guess_mode(args, config):
Expand Down Expand Up @@ -300,6 +303,9 @@ def configure_logger(debug=False):


def run(manual_args=None):
if manual_args is None:
manual_args = sys.argv[1:]

args = parse_args(manual_args)

configure_logger(args.debug)
Expand Down
14 changes: 11 additions & 3 deletions jrnl/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import subprocess
import sys
import tempfile
import textwrap
from typing import Callable, Optional
import unicodedata

Expand Down Expand Up @@ -172,10 +173,17 @@ def get_text_from_editor(config, template=""):

try:
subprocess.call(
shlex.split(config["editor"], posix="win" not in sys.platform) + [tmpfile]
shlex.split(config["editor"], posix="win32" not in sys.platform) + [tmpfile]
)
except AttributeError:
subprocess.call(config["editor"] + [tmpfile])
except Exception as e:
error_msg = f"""
{ERROR_COLOR}{str(e)}{RESET_COLOR}

Please check the 'editor' key in your config file for errors:
{repr(config['editor'])}
"""
print(textwrap.dedent(error_msg).strip(), file=sys.stderr)
exit(1)

with open(tmpfile, "r", encoding="utf-8") as f:
raw = f.read()
Expand Down