{"action":"created","comment":{"url":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls/comments/54666492","id":54666492,"diff_hunk":"@@ -404,7 +417,15 @@ exports.generateAceApiCompleter = function (functionFilter, dropletConfig) {\n         callback(null, []);\n         return;\n       }\n-      callback(null, apis);\n+      var line = session.getLine(pos.row);\n+      var identifier = acUtil.retrievePrecedingIdentifier(line, pos.column);\n+      if (pos.column > (identifier.length + 1) &&\n+          line[pos.column - identifier.length - 1] === '.') {","path":"apps/src/dropletUtils.js","position":112,"original_position":112,"commit_id":"167b6f8176ae9db438a4ad0bb8ba203ae8661419","original_commit_id":"167b6f8176ae9db438a4ad0bb8ba203ae8661419","user":{"login":"cpirich","id":5429146,"avatar_url":"https://avatars.githubusercontent.com/u/5429146?v=3","gravatar_id":"","url":"https://api.github.com/users/cpirich","html_url":"https://github.com/cpirich","followers_url":"https://api.github.com/users/cpirich/followers","following_url":"https://api.github.com/users/cpirich/following{/other_user}","gists_url":"https://api.github.com/users/cpirich/gists{/gist_id}","starred_url":"https://api.github.com/users/cpirich/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cpirich/subscriptions","organizations_url":"https://api.github.com/users/cpirich/orgs","repos_url":"https://api.github.com/users/cpirich/repos","events_url":"https://api.github.com/users/cpirich/events{/privacy}","received_events_url":"https://api.github.com/users/cpirich/received_events","type":"User","site_admin":false},"body":"Not sure there is an error. I intentionally had it go in the else case if the line begins with a dot. I wanted it to only go into the new methods completer if there is both a dot and something before the dot before the current identifier. If the line is too short to have something before the dot, then we do what we also did in the past. I'll make sure I add a comment. And can extract a helper to improve readability.\n\nThe other comment needed is that we're not doing a sophisticated parse of the whole document - ace autocomplete is much more simplistic. So multiline expressions won't get autocomplete.\n\nWe may eventually want to examine the identifier preceding the dot more carefully. I have a note to try to avoid autocompleting `1.` since you're probably typing a decimal. But technically `(1).` could be autocompleted with `toString()`, so this is a little tricky. \n\nBut thanks for examining in such detail regardless!\n\n\n\n> On Mar 1, 2016, at 4:32 PM, Brad Buchanan <notifications@github.com> wrote:\n> \n> In apps/src/dropletUtils.js:\n> \n> > @@ -404,7 +417,15 @@ exports.generateAceApiCompleter = function (functionFilter, dropletConfig) {\n> >          callback(null, []);\n> >          return;\n> >        }\n> > -      callback(null, apis);\n> > +      var line = session.getLine(pos.row);\n> > +      var identifier = acUtil.retrievePrecedingIdentifier(line, pos.column);\n> > +      if (pos.column > (identifier.length + 1) &&\n> > +          line[pos.column - identifier.length - 1] === '.') {\n> Grabbed @Hamms to help me parse this, and he pointed out that the second condition is correct and checks whether the cursor is inside a symbol that immediately follows a dot.\n> \n> We eventually tracked down a failing case: a line that begins with . will incorrectly take the else case even when the cursor is in such a position. That's due to an off-by-one error in the first condition; which, incidentally, is unneeded since indexing outside of a string will just return undefined.\n> \n> But that off-by-one error took way too much work to find. Let's just extract and test a isCursorInSymbolAfterDot helper, please?\n> \n> —\n> Reply to this email directly or view it on GitHub.\n> \n","created_at":"2016-03-02T01:29:48Z","updated_at":"2016-03-02T01:29:48Z","html_url":"https://github.com/code-dot-org/code-dot-org/pull/7070#discussion_r54666492","pull_request_url":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls/7070","_links":{"self":{"href":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls/comments/54666492"},"html":{"href":"https://github.com/code-dot-org/code-dot-org/pull/7070#discussion_r54666492"},"pull_request":{"href":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls/7070"}}},"pull_request":{"url":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls/7070","id":61316393,"html_url":"https://github.com/code-dot-org/code-dot-org/pull/7070","diff_url":"https://github.com/code-dot-org/code-dot-org/pull/7070.diff","patch_url":"https://github.com/code-dot-org/code-dot-org/pull/7070.patch","issue_url":"https://api.github.com/repos/code-dot-org/code-dot-org/issues/7070","number":7070,"state":"open","locked":false,"title":"Autocomplete and tooltip changes","user":{"login":"cpirich","id":5429146,"avatar_url":"https://avatars.githubusercontent.com/u/5429146?v=3","gravatar_id":"","url":"https://api.github.com/users/cpirich","html_url":"https://github.com/cpirich","followers_url":"https://api.github.com/users/cpirich/followers","following_url":"https://api.github.com/users/cpirich/following{/other_user}","gists_url":"https://api.github.com/users/cpirich/gists{/gist_id}","starred_url":"https://api.github.com/users/cpirich/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cpirich/subscriptions","organizations_url":"https://api.github.com/users/cpirich/orgs","repos_url":"https://api.github.com/users/cpirich/repos","events_url":"https://api.github.com/users/cpirich/events{/privacy}","received_events_url":"https://api.github.com/users/cpirich/received_events","type":"User","site_admin":false},"body":"* Enhance autocomplete system to understand the `.` character. Outside of global objects in our autocomplete system like `console.log` and `Math.min`, typing the `.` character after an identifier will dismiss the autocomplete popup. A new one will appear once the first character is typed after the `.` and that one will be scoped only to methods or properties on objects (as designated with the `*.method` or `?.method` syntax already used by droplet).\r\n* Changed tooltip system to be more flexible without resorting to setting `signatureOverride`: (1) allow for `tipPrefix` on the block (used for `[string].`) and (2) store `isProperty` when the block's `type` is `property`\r\n* Changed tooltip system to use `paletteParams` from `dropletConfig`. Though these can still be override in the localized strings files, that should be the exception. I deleted all of the localized strings that contained parameter names that matched those already stored in the block's `paletteParams`\r\n* Changed how `blockPrefix` is treated, so it is truly a prefix appending on the front the `block.func` property. Also, made it apply to both properties and functions.\r\n* Some minor dropletConfig changes in applab to match the changes above.\r\n* Cleanup of applab tooltip strings across the board. Added many parameter descriptions that were missing.\r\n* Massive rework of gamelab `levels.js` and `dropletConfig.js` to take advantage of the new system above.\r\n","created_at":"2016-03-01T22:04:25Z","updated_at":"2016-03-02T01:29:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8a90c0f2dbf4f09c6eb12506b9524b2aff48a64b","assignee":{"login":"islemaster","id":1615761,"avatar_url":"https://avatars.githubusercontent.com/u/1615761?v=3","gravatar_id":"","url":"https://api.github.com/users/islemaster","html_url":"https://github.com/islemaster","followers_url":"https://api.github.com/users/islemaster/followers","following_url":"https://api.github.com/users/islemaster/following{/other_user}","gists_url":"https://api.github.com/users/islemaster/gists{/gist_id}","starred_url":"https://api.github.com/users/islemaster/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/islemaster/subscriptions","organizations_url":"https://api.github.com/users/islemaster/orgs","repos_url":"https://api.github.com/users/islemaster/repos","events_url":"https://api.github.com/users/islemaster/events{/privacy}","received_events_url":"https://api.github.com/users/islemaster/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls/7070/commits","review_comments_url":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls/7070/comments","review_comment_url":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls/comments{/number}","comments_url":"https://api.github.com/repos/code-dot-org/code-dot-org/issues/7070/comments","statuses_url":"https://api.github.com/repos/code-dot-org/code-dot-org/statuses/167b6f8176ae9db438a4ad0bb8ba203ae8661419","head":{"label":"code-dot-org:autocomplete_and_tooltip_changes","ref":"autocomplete_and_tooltip_changes","sha":"167b6f8176ae9db438a4ad0bb8ba203ae8661419","user":{"login":"code-dot-org","id":5124627,"avatar_url":"https://avatars.githubusercontent.com/u/5124627?v=3","gravatar_id":"","url":"https://api.github.com/users/code-dot-org","html_url":"https://github.com/code-dot-org","followers_url":"https://api.github.com/users/code-dot-org/followers","following_url":"https://api.github.com/users/code-dot-org/following{/other_user}","gists_url":"https://api.github.com/users/code-dot-org/gists{/gist_id}","starred_url":"https://api.github.com/users/code-dot-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/code-dot-org/subscriptions","organizations_url":"https://api.github.com/users/code-dot-org/orgs","repos_url":"https://api.github.com/users/code-dot-org/repos","events_url":"https://api.github.com/users/code-dot-org/events{/privacy}","received_events_url":"https://api.github.com/users/code-dot-org/received_events","type":"Organization","site_admin":false},"repo":{"id":24250009,"name":"code-dot-org","full_name":"code-dot-org/code-dot-org","owner":{"login":"code-dot-org","id":5124627,"avatar_url":"https://avatars.githubusercontent.com/u/5124627?v=3","gravatar_id":"","url":"https://api.github.com/users/code-dot-org","html_url":"https://github.com/code-dot-org","followers_url":"https://api.github.com/users/code-dot-org/followers","following_url":"https://api.github.com/users/code-dot-org/following{/other_user}","gists_url":"https://api.github.com/users/code-dot-org/gists{/gist_id}","starred_url":"https://api.github.com/users/code-dot-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/code-dot-org/subscriptions","organizations_url":"https://api.github.com/users/code-dot-org/orgs","repos_url":"https://api.github.com/users/code-dot-org/repos","events_url":"https://api.github.com/users/code-dot-org/events{/privacy}","received_events_url":"https://api.github.com/users/code-dot-org/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/code-dot-org/code-dot-org","description":"The code powering code.org and studio.code.org","fork":false,"url":"https://api.github.com/repos/code-dot-org/code-dot-org","forks_url":"https://api.github.com/repos/code-dot-org/code-dot-org/forks","keys_url":"https://api.github.com/repos/code-dot-org/code-dot-org/keys{/key_id}","collaborators_url":"https://api.github.com/repos/code-dot-org/code-dot-org/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/code-dot-org/code-dot-org/teams","hooks_url":"https://api.github.com/repos/code-dot-org/code-dot-org/hooks","issue_events_url":"https://api.github.com/repos/code-dot-org/code-dot-org/issues/events{/number}","events_url":"https://api.github.com/repos/code-dot-org/code-dot-org/events","assignees_url":"https://api.github.com/repos/code-dot-org/code-dot-org/assignees{/user}","branches_url":"https://api.github.com/repos/code-dot-org/code-dot-org/branches{/branch}","tags_url":"https://api.github.com/repos/code-dot-org/code-dot-org/tags","blobs_url":"https://api.github.com/repos/code-dot-org/code-dot-org/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/code-dot-org/code-dot-org/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/code-dot-org/code-dot-org/git/refs{/sha}","trees_url":"https://api.github.com/repos/code-dot-org/code-dot-org/git/trees{/sha}","statuses_url":"https://api.github.com/repos/code-dot-org/code-dot-org/statuses/{sha}","languages_url":"https://api.github.com/repos/code-dot-org/code-dot-org/languages","stargazers_url":"https://api.github.com/repos/code-dot-org/code-dot-org/stargazers","contributors_url":"https://api.github.com/repos/code-dot-org/code-dot-org/contributors","subscribers_url":"https://api.github.com/repos/code-dot-org/code-dot-org/subscribers","subscription_url":"https://api.github.com/repos/code-dot-org/code-dot-org/subscription","commits_url":"https://api.github.com/repos/code-dot-org/code-dot-org/commits{/sha}","git_commits_url":"https://api.github.com/repos/code-dot-org/code-dot-org/git/commits{/sha}","comments_url":"https://api.github.com/repos/code-dot-org/code-dot-org/comments{/number}","issue_comment_url":"https://api.github.com/repos/code-dot-org/code-dot-org/issues/comments{/number}","contents_url":"https://api.github.com/repos/code-dot-org/code-dot-org/contents/{+path}","compare_url":"https://api.github.com/repos/code-dot-org/code-dot-org/compare/{base}...{head}","merges_url":"https://api.github.com/repos/code-dot-org/code-dot-org/merges","archive_url":"https://api.github.com/repos/code-dot-org/code-dot-org/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/code-dot-org/code-dot-org/downloads","issues_url":"https://api.github.com/repos/code-dot-org/code-dot-org/issues{/number}","pulls_url":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls{/number}","milestones_url":"https://api.github.com/repos/code-dot-org/code-dot-org/milestones{/number}","notifications_url":"https://api.github.com/repos/code-dot-org/code-dot-org/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/code-dot-org/code-dot-org/labels{/name}","releases_url":"https://api.github.com/repos/code-dot-org/code-dot-org/releases{/id}","deployments_url":"https://api.github.com/repos/code-dot-org/code-dot-org/deployments","created_at":"2014-09-20T00:46:11Z","updated_at":"2016-03-01T04:16:25Z","pushed_at":"2016-03-02T01:28:39Z","git_url":"git://github.com/code-dot-org/code-dot-org.git","ssh_url":"git@github.com:code-dot-org/code-dot-org.git","clone_url":"https://github.com/code-dot-org/code-dot-org.git","svn_url":"https://github.com/code-dot-org/code-dot-org","homepage":"http://code.org","size":4175439,"stargazers_count":94,"watchers_count":94,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":49,"mirror_url":null,"open_issues_count":76,"forks":49,"open_issues":76,"watchers":94,"default_branch":"staging"}},"base":{"label":"code-dot-org:staging","ref":"staging","sha":"968f542e64b96e3ec9e5c7c86cdb070d69c1c0c8","user":{"login":"code-dot-org","id":5124627,"avatar_url":"https://avatars.githubusercontent.com/u/5124627?v=3","gravatar_id":"","url":"https://api.github.com/users/code-dot-org","html_url":"https://github.com/code-dot-org","followers_url":"https://api.github.com/users/code-dot-org/followers","following_url":"https://api.github.com/users/code-dot-org/following{/other_user}","gists_url":"https://api.github.com/users/code-dot-org/gists{/gist_id}","starred_url":"https://api.github.com/users/code-dot-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/code-dot-org/subscriptions","organizations_url":"https://api.github.com/users/code-dot-org/orgs","repos_url":"https://api.github.com/users/code-dot-org/repos","events_url":"https://api.github.com/users/code-dot-org/events{/privacy}","received_events_url":"https://api.github.com/users/code-dot-org/received_events","type":"Organization","site_admin":false},"repo":{"id":24250009,"name":"code-dot-org","full_name":"code-dot-org/code-dot-org","owner":{"login":"code-dot-org","id":5124627,"avatar_url":"https://avatars.githubusercontent.com/u/5124627?v=3","gravatar_id":"","url":"https://api.github.com/users/code-dot-org","html_url":"https://github.com/code-dot-org","followers_url":"https://api.github.com/users/code-dot-org/followers","following_url":"https://api.github.com/users/code-dot-org/following{/other_user}","gists_url":"https://api.github.com/users/code-dot-org/gists{/gist_id}","starred_url":"https://api.github.com/users/code-dot-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/code-dot-org/subscriptions","organizations_url":"https://api.github.com/users/code-dot-org/orgs","repos_url":"https://api.github.com/users/code-dot-org/repos","events_url":"https://api.github.com/users/code-dot-org/events{/privacy}","received_events_url":"https://api.github.com/users/code-dot-org/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/code-dot-org/code-dot-org","description":"The code powering code.org and studio.code.org","fork":false,"url":"https://api.github.com/repos/code-dot-org/code-dot-org","forks_url":"https://api.github.com/repos/code-dot-org/code-dot-org/forks","keys_url":"https://api.github.com/repos/code-dot-org/code-dot-org/keys{/key_id}","collaborators_url":"https://api.github.com/repos/code-dot-org/code-dot-org/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/code-dot-org/code-dot-org/teams","hooks_url":"https://api.github.com/repos/code-dot-org/code-dot-org/hooks","issue_events_url":"https://api.github.com/repos/code-dot-org/code-dot-org/issues/events{/number}","events_url":"https://api.github.com/repos/code-dot-org/code-dot-org/events","assignees_url":"https://api.github.com/repos/code-dot-org/code-dot-org/assignees{/user}","branches_url":"https://api.github.com/repos/code-dot-org/code-dot-org/branches{/branch}","tags_url":"https://api.github.com/repos/code-dot-org/code-dot-org/tags","blobs_url":"https://api.github.com/repos/code-dot-org/code-dot-org/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/code-dot-org/code-dot-org/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/code-dot-org/code-dot-org/git/refs{/sha}","trees_url":"https://api.github.com/repos/code-dot-org/code-dot-org/git/trees{/sha}","statuses_url":"https://api.github.com/repos/code-dot-org/code-dot-org/statuses/{sha}","languages_url":"https://api.github.com/repos/code-dot-org/code-dot-org/languages","stargazers_url":"https://api.github.com/repos/code-dot-org/code-dot-org/stargazers","contributors_url":"https://api.github.com/repos/code-dot-org/code-dot-org/contributors","subscribers_url":"https://api.github.com/repos/code-dot-org/code-dot-org/subscribers","subscription_url":"https://api.github.com/repos/code-dot-org/code-dot-org/subscription","commits_url":"https://api.github.com/repos/code-dot-org/code-dot-org/commits{/sha}","git_commits_url":"https://api.github.com/repos/code-dot-org/code-dot-org/git/commits{/sha}","comments_url":"https://api.github.com/repos/code-dot-org/code-dot-org/comments{/number}","issue_comment_url":"https://api.github.com/repos/code-dot-org/code-dot-org/issues/comments{/number}","contents_url":"https://api.github.com/repos/code-dot-org/code-dot-org/contents/{+path}","compare_url":"https://api.github.com/repos/code-dot-org/code-dot-org/compare/{base}...{head}","merges_url":"https://api.github.com/repos/code-dot-org/code-dot-org/merges","archive_url":"https://api.github.com/repos/code-dot-org/code-dot-org/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/code-dot-org/code-dot-org/downloads","issues_url":"https://api.github.com/repos/code-dot-org/code-dot-org/issues{/number}","pulls_url":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls{/number}","milestones_url":"https://api.github.com/repos/code-dot-org/code-dot-org/milestones{/number}","notifications_url":"https://api.github.com/repos/code-dot-org/code-dot-org/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/code-dot-org/code-dot-org/labels{/name}","releases_url":"https://api.github.com/repos/code-dot-org/code-dot-org/releases{/id}","deployments_url":"https://api.github.com/repos/code-dot-org/code-dot-org/deployments","created_at":"2014-09-20T00:46:11Z","updated_at":"2016-03-01T04:16:25Z","pushed_at":"2016-03-02T01:28:39Z","git_url":"git://github.com/code-dot-org/code-dot-org.git","ssh_url":"git@github.com:code-dot-org/code-dot-org.git","clone_url":"https://github.com/code-dot-org/code-dot-org.git","svn_url":"https://github.com/code-dot-org/code-dot-org","homepage":"http://code.org","size":4175439,"stargazers_count":94,"watchers_count":94,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":49,"mirror_url":null,"open_issues_count":76,"forks":49,"open_issues":76,"watchers":94,"default_branch":"staging"}},"_links":{"self":{"href":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls/7070"},"html":{"href":"https://github.com/code-dot-org/code-dot-org/pull/7070"},"issue":{"href":"https://api.github.com/repos/code-dot-org/code-dot-org/issues/7070"},"comments":{"href":"https://api.github.com/repos/code-dot-org/code-dot-org/issues/7070/comments"},"review_comments":{"href":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls/7070/comments"},"review_comment":{"href":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/code-dot-org/code-dot-org/pulls/7070/commits"},"statuses":{"href":"https://api.github.com/repos/code-dot-org/code-dot-org/statuses/167b6f8176ae9db438a4ad0bb8ba203ae8661419"}}}}