-
Notifications
You must be signed in to change notification settings - Fork 313
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
Do not autocomplete if only whitespace precedes cursor #410
base: develop
Are you sure you want to change the base?
Changes from 5 commits
8145e39
7651758
8044af6
55bfd24
07f723c
23d0cbb
fbe76e0
833eb66
785a976
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,12 +45,13 @@ public function activate() | |
* Handle readline completion. | ||
* | ||
* @param string $input Readline current word | ||
* @param int $index Current word index | ||
* @param int $start Readline start match | ||
* @param int $end Readline end match | ||
* @param array $info readline_info() data | ||
* | ||
* @return array | ||
*/ | ||
public function processCallback($input, $index, $info = array()) | ||
public function processCallback($input, $start, $end, $info = array()) | ||
{ | ||
// Some (Windows?) systems provide incomplete `readline_info`, so let's | ||
// try to work around it. | ||
|
@@ -62,6 +63,10 @@ public function processCallback($input, $index, $info = array()) | |
$line = $input; | ||
} | ||
|
||
if ($this->shouldInsertOnlyTab($line, $start, $end)) { | ||
return array("\t"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. because of the magic space inserted after tab completion, this inserts five spaces for the first tab stop, then nine spaces for each additional tab stop. why don't we hijack this and return three spaces? then it's always four space indents :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It inserts a tab character, not spaces. I'm definitely not a fan of replacing it with space characters, as those are different (no matter what you think of tabs vs spaces) and substituting one for the other silently can never be what you want. The tab + space behaviour is sort of vexing, but it's not something I can realistically solve in a way that doesn't break everything in environments that do work properly (for example ones that have the path from php/php-src#2720 applied). What I can probably do is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could add in a setting for this and apply it to every autocompletion, thinking about it. Until the patch I mentioned works that's a sort of viable workaround to get autocompletion as you'd expect from an IDE. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wait no, that won't work. The space is appended after the completion - so a backspace that is inserted will actually just remove the tab character entirely. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i understand that tabs and spaces are different. but practically, one looks like you'd expect, and the other looks really bad. so ¯\_(ツ)_/¯ |
||
} | ||
|
||
$tokens = token_get_all('<?php ' . $line); | ||
|
||
// remove whitespaces | ||
|
@@ -81,19 +86,38 @@ public function processCallback($input, $index, $info = array()) | |
return !empty($matches) ? $matches : array(''); | ||
} | ||
|
||
/** | ||
* @param string $line Readline current line | ||
* @param int $start The start of the readline input | ||
* @param int $end The end of the readline input | ||
* | ||
* @return bool true if the characters before $index are only whitespace | ||
* | ||
* @internal param int $index Current word index | ||
*/ | ||
private function shouldInsertOnlyTab($line, $start, $end) | ||
{ | ||
$precedingInput = substr($line, 0, $end); | ||
|
||
$trimmedInput = trim($precedingInput); | ||
|
||
return empty($trimmedInput); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't use empty, use >>> empty('0')
=> true |
||
} | ||
|
||
/** | ||
* The readline_completion_function callback handler. | ||
* | ||
* @see processCallback | ||
* | ||
* @param $input | ||
* @param $index | ||
* @param string $input | ||
* @param int $start | ||
* @param int $end | ||
* | ||
* @return array | ||
*/ | ||
public function callback($input, $index) | ||
public function callback($input, $start, $end) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do all the possible combinations of readline and libedit and php versions all provide if not, should we fall back to the end in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I looked here: https://github.com/php/php-src/blob/master/ext/readline/readline.c#L490 And I saw that For editline / libedit, editline/readline.h is included. This has in editline's readline.c I see this:
Where
Which leads me to believe that it does the same thing (http://www.delorie.com/gnu/docs/readline/rlman_28.html tells me that Even if that is in question, from the https://github.com/php/php-src/blob/master/ext/readline/readline.c#L257 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. However, having dived into it this far, I cannot help but wonder how this works - I had interpreted |
||
{ | ||
return $this->processCallback($input, $index, readline_info()); | ||
return $this->processCallback($input, $start, $end, readline_info()); | ||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unfortunately this is a public method, so we won't be able to break backwards compatibility. right now.
but!
$info['end']
is supposed to be a thing already, and we're using it below. we could work the$end
param from the callback into the$info
array to augment and/or replace that one, or we could just use that one?or we could add the
$end
param to the end here, but that's just a bit awkward.or we could rename this method and add a deprecated stub of a method called
processCallback
that still takes the old arguments. i think i like this third option best :)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's actually the function passed to
readline_completion_function
that needs the change, which is also public. Refactoring that in a non-breaking manner gives me a large headache, so I reverted it back to the old (and admittedly broken) way. I usepoint
now, which is more in line with what should happen anyway.