diff --git a/src/editor/CodeHintList.js b/src/editor/CodeHintList.js index 964e1ed447c..5a132281d75 100644 --- a/src/editor/CodeHintList.js +++ b/src/editor/CodeHintList.js @@ -152,7 +152,7 @@ define(function (require, exports, module) { ViewUtils.scrollElementIntoView($view, $item, false); if (this.handleHighlight) { - this.handleHighlight($item.find("a")); + this.handleHighlight($item.find("a"), this.$hintMenu.find("#codehint-desc")); } } }; @@ -191,6 +191,7 @@ define(function (require, exports, module) { this.hints = hintObj.hints; this.hints.handleWideResults = hintObj.handleWideResults; + this.enableDescription = hintObj.enableDescription; // if there is no match, assume name is already a formatted jQuery // object; otherwise, use match to format name for display. @@ -265,6 +266,17 @@ define(function (require, exports, module) { // attach to DOM $parent.append($ul); + $parent.find(".hint-list-offset").remove(); + $("
").appendTo($parent); + + // If a a description field requested attach one + if (this.enableDescription) { + // Remove the desc element first to ensure DOM order + $parent.find("#codehint-desc").remove(); + $parent.append(""); + $ul.addClass("withDesc"); + $parent.find(".hint-list-offset").addClass("withDesc"); + } this._setSelectedIndex(selectInitial ? 0 : -1); } }; @@ -283,7 +295,9 @@ define(function (require, exports, module) { textHeight = this.editor.getTextHeight(), $window = $(window), $menuWindow = this.$hintMenu.children("ul"), - menuHeight = $menuWindow.outerHeight(); + $descElement = this.$hintMenu.find("#codehint-desc"), + descOverhang = $descElement.length === 1 ? $descElement.height() : 0, + menuHeight = $menuWindow.outerHeight() + descOverhang; // TODO Ty: factor out menu repositioning logic so code hints and Context menus share code // adjust positioning so menu is not clipped off bottom or right @@ -304,6 +318,13 @@ define(function (require, exports, module) { availableWidth = menuWidth + Math.abs(rightOverhang); } + //Creating the offset element for hint description element + var descOffset = this.$hintMenu.find("ul.dropdown-menu")[0].getBoundingClientRect().height; + if (descOffset === 0) { + descOffset = menuHeight - descOverhang; + } + this.$hintMenu.find(".hint-list-offset").css("height", descOffset - 1); + return {left: posLeft, top: posTop, width: availableWidth}; }; diff --git a/src/editor/CodeHintManager.js b/src/editor/CodeHintManager.js index 8a2cdf28e69..925ffcb61ec 100644 --- a/src/editor/CodeHintManager.js +++ b/src/editor/CodeHintManager.js @@ -507,10 +507,21 @@ define(function (require, exports, module) { sessionEditor = editor; hintList = new CodeHintList(sessionEditor, insertHintOnTab, maxCodeHints); - hintList.onHighlight(function ($hint) { - // If the current hint provider listening for hint item highlight change - if (sessionProvider.onHighlight) { - sessionProvider.onHighlight($hint); + hintList.onHighlight(function ($hint, $hintDescContainer) { + if (hintList.enableDescription && $hintDescContainer && $hintDescContainer.length) { + // If the current hint provider listening for hint item highlight change + if (sessionProvider.onHighlight) { + sessionProvider.onHighlight($hint, $hintDescContainer); + } + + // Update the hint description + if (sessionProvider.updateHintDescription) { + sessionProvider.updateHintDescription($hint, $hintDescContainer); + } + } else { + if (sessionProvider.onHighlight) { + sessionProvider.onHighlight($hint); + } } }); hintList.onSelect(function (hint) { diff --git a/src/extensions/default/PhpTooling/CodeHintsProvider.js b/src/extensions/default/PhpTooling/CodeHintsProvider.js index 395c9c599f2..3f54d82f2e1 100644 --- a/src/extensions/default/PhpTooling/CodeHintsProvider.js +++ b/src/extensions/default/PhpTooling/CodeHintsProvider.js @@ -36,30 +36,27 @@ define(function (require, exports, module) { preferPrefixMatches: true }); - var phpSuperGlobalVariables = JSON.parse(require("text!phpGlobals.json")); + var phpSuperGlobalVariables = JSON.parse(require("text!phpGlobals.json")), + hintType = { + "2": "Method", + "3": "Function", + "4": "Constructor", + "6": "Variable", + "7": "Class", + "8": "Interface", + "9": "Module", + "10": "Property", + "14": "Keyword", + "21": "Constant" + }; function CodeHintsProvider(client) { this.defaultCodeHintProviders = new DefaultProviders.CodeHintsProvider(client); } - function formatTypeDataForToken($hintObj, token) { + function setStyleAndCacheToken($hintObj, token) { $hintObj.addClass('brackets-hints-with-type-details'); - if (token.detail) { - if (token.detail.trim() !== '?') { - if (token.detail.length < 30) { - $('' + token.detail.split('->').join(':').toString().trim() + '').appendTo($hintObj).addClass("brackets-hints-type-details"); - } - $('' + token.detail.split('->').join(':').toString().trim() + '').appendTo($hintObj).addClass("hint-description"); - } - } else { - if (token.keyword) { - $('keyword').appendTo($hintObj).addClass("brackets-hints-keyword"); - } - } - if (token.documentation) { - $hintObj.attr('title', token.documentation); - $('').text(token.documentation.trim()).appendTo($hintObj).addClass("hint-doc"); - } + $hintObj.data('completionItem', token); } function filterWithQueryAndMatcher(hints, query) { @@ -146,7 +143,7 @@ define(function (require, exports, module) { } $fHint.data("token", element); - formatTypeDataForToken($fHint, element); + setStyleAndCacheToken($fHint, element); hints.push($fHint); }); } @@ -154,6 +151,7 @@ define(function (require, exports, module) { var token = self.query; $deferredHints.resolve({ "hints": hints, + "enableDescription": true, "selectInitial": token && /\S/.test(token) && isNaN(parseInt(token, 10)) // If the active token is blank then don't put default selection }); }).fail(function () { @@ -167,5 +165,33 @@ define(function (require, exports, module) { return this.defaultCodeHintProviders.insertHint($hint); }; + CodeHintsProvider.prototype.updateHintDescription = function ($hint, $hintDescContainer) { + var $hintObj = $hint.find('.brackets-hints-with-type-details'), + token = $hintObj.data('completionItem'), + $desc = $('