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

Add more variables (cont.) #4652

Merged
merged 8 commits into from Apr 17, 2019
Merged

Conversation

jgkamat
Copy link
Member

@jgkamat jgkamat commented Mar 17, 2019

This is a continuation of #1937

I'm going to ignore the extremely inefficient and unnecessary dict creation/loop in the interest of making the diff as small as possible.

Together with #4651, will close #4647.


This change is Reviewable

kobezda and others added 6 commits September 9, 2016 13:43
This adds more variables, in particular:
   {url:domain}
   {url:auth}
   {url:scheme}
   {url:user}
   {url:password}
   {url:host}
   {url:port}
   {url:path}
   {url:query}
Variables such as {url} and {selection} can now be explicitly
escaped by prefixing them with a backslash: \{url}

Only valid variables that would've been replaced are escaped,
so '\{notavariable}' stays '\{notavariable}'

See qutebrowser#1861
@@ -441,6 +441,49 @@ Feature: Various utility commands.
And I run :message-info {clipboard}bar{url}
Then the message "{url}barhttp://localhost:*/hello.txt" should be shown

Scenario: Variable {url:pretty}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance you could take a quick look into what it'd take to make those unit rather than end2end tests? If it ends up not being possible easily then those are fine, but if it's possible, I'd strongly prefer that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I can make it unit tests (because most variable expansion requires a tabbedbrowser, which I'm not entirey sure I can properly mock), but I did get it to a python e2e test, does that sound ok?

Then the message "foo" should be shown

# Tests for HTTP basic auth variables are missing here, pytest-bdd bug
# https://github.com/The-Compiler/qutebrowser/pull/1921#issuecomment-244695985
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in September 2016, so it should be possible to add those.

@The-Compiler
Copy link
Member

I'm going to ignore the extremely inefficient and unnecessary dict creation/loop

Can you elaborate? I'm getting a bit worried we're starting to micro-optimize things which don't actually make a difference in practice (a few microseconds or whatever when executing a command really doesn't make a difference). How is it "extremely" inefficient? Why is it unnecessary? I'm really grateful for your performance work in the areas where it's really needed (and there are some of those, granted), but when deciding between readability/simplicity vs. performance, I'm still going to default to the former, especially when there's no evidence that it makes a difference in practice.

@jgkamat
Copy link
Member Author

jgkamat commented Mar 19, 2019 via email

@user202729
Copy link
Contributor

user202729 commented Mar 25, 2019

It's not exactly "extremely inefficient", but I can see no benefit in doing it - it doesn't make the code simpler, or easier to read, or something like that.

@The-Compiler
Copy link
Member

Does it make a difference in this case? Probably not, but that's only because
there's a much larger version of this same problem (the config system
iterating over dicts and keybindings iterating over the binding dict)
overshadowing everything else.

Thanks for the explanation. Before this, I never realized that you regard this specific thing as a (recurring) problem - as far as I remember, you never told me 😉

I agree it's something which should be done rather sparingly, but in some cases there isn't really a better solution - like for matching keybindings IIRC, where the matching algorithm isn't just a fixed lookup.

Those things could be a list of tuples instead (because they aren't really used as a dict), but that wouldn't really change anything either, and just make the syntax more awkward, so I don't really see the gain. They probably should be more fitting data structures (perhaps a trie for keybindings?) though.

Either way, I'll try to keep an eye on it in the future.

As for this specific case:

Maybe it's just me, but sending code off to (I'm guessing) ~1000s of machines to run pointless loops over hashmaps dosen't feel right - it's easily preventable and wastes the user's resources.

It's not exactly "extremely inefficient", but I can see no benefit in doing it - it doesn't make the code simpler, or easier to read, or something like that.

So what would you (both) suggest instead? Note that:

  • If no replacement is used, commands should be able to execute without a tabbed_browser/URL being available.
  • Using {{url}} should escape the {url} variable.

Here's what I can think of:

  • Moving the variables dict and replace_variables into CommandRunner, and filling it up with the escaped replacements in __init__
  • For every replacement like url, add {url}: lambda: {url} hardcoded into the dict (with the cost of making it double as verbose)
  • Have a real commandline parser (the goal of Less special cases for commandline parsing #2017)

I'm open for suggestions - I'd probably go for 1. in the short term and 3. in the long term. 2. would avoid the loop, but it seems to be like that would indeed make the code harder to read (or at least more verbose).

Copy link
Member

@The-Compiler The-Compiler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some small issues with the tests, but I'll fix that up while merging.



def test_command_expansion_clipboard(quteproc):
quteproc.send_cmd(':debug-set-fake-clipboard "{}"'.format('foo'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting with a constant string makes little sense...

command_expansion_base(
quteproc, '{clipboard}bar{url}',
"foobarhttp://localhost:*/hello.txt")
quteproc.send_cmd(':debug-set-fake-clipboard "{}"'.format('{{url}}'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same



def test_command_expansion_basic_auth(quteproc, server):
url = 'http://user1:password1@localhost:{port}/basic-auth/user1/password1' \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer adding parens to backslash continuation

@user202729
Copy link
Contributor

user202729 commented Apr 17, 2019

@The-Compiler Regarding the "related" problem you mentioned: I implemented trie data structure for keybindings (https://paste.the-compiler.org/view/c15f385c (by the way the captcha says "type in the letters" while reCaptcha isn't that)), however the implementation is incomplete:

  • Partial key sequence suggestion or config bind/unbind (on_config_changed) still traverse the whole dict.
  • update method is not implemented (although this one is easy to implement, just loop over all items)

I may open a PR later, when it works properly and I can check that it does improve performance.

@The-Compiler The-Compiler merged commit 700493a into qutebrowser:master Apr 17, 2019
@The-Compiler
Copy link
Member

@user202729 Nice! I opened a separate issue for that: #4721

@jgkamat and @kobezda: Thanks for the contribution!

@jgkamat jgkamat deleted the more-variables branch April 18, 2019 03:26
@jgkamat
Copy link
Member Author

jgkamat commented Apr 18, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

:yank markdown (and asciidoc and html)
5 participants