python-hint.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. (function () {
  2. function forEach(arr, f) {
  3. for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
  4. }
  5. function arrayContains(arr, item) {
  6. if (!Array.prototype.indexOf) {
  7. var i = arr.length;
  8. while (i--) {
  9. if (arr[i] === item) {
  10. return true;
  11. }
  12. }
  13. return false;
  14. }
  15. return arr.indexOf(item) != -1;
  16. }
  17. function scriptHint(editor, _keywords, getToken) {
  18. // Find the token at the cursor
  19. var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
  20. // If it's not a 'word-style' token, ignore the token.
  21. if (!/^[\w$_]*$/.test(token.string)) {
  22. token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
  23. className: token.string == ":" ? "python-type" : null};
  24. }
  25. if (!context) var context = [];
  26. context.push(tprop);
  27. var completionList = getCompletions(token, context);
  28. completionList = completionList.sort();
  29. //prevent autocomplete for last word, instead show dropdown with one word
  30. if(completionList.length == 1) {
  31. completionList.push(" ");
  32. }
  33. return {list: completionList,
  34. from: CodeMirror.Pos(cur.line, token.start),
  35. to: CodeMirror.Pos(cur.line, token.end)};
  36. }
  37. CodeMirror.pythonHint = function(editor) {
  38. return scriptHint(editor, pythonKeywordsU, function (e, cur) {return e.getTokenAt(cur);});
  39. };
  40. var pythonKeywords = "and del from not while as elif global or with assert else if pass yield"
  41. + "break except import print class exec in raise continue finally is return def for lambda try";
  42. var pythonKeywordsL = pythonKeywords.split(" ");
  43. var pythonKeywordsU = pythonKeywords.toUpperCase().split(" ");
  44. var pythonBuiltins = "abs divmod input open staticmethod all enumerate int ord str "
  45. + "any eval isinstance pow sum basestring execfile issubclass print super"
  46. + "bin file iter property tuple bool filter len range type"
  47. + "bytearray float list raw_input unichr callable format locals reduce unicode"
  48. + "chr frozenset long reload vars classmethod getattr map repr xrange"
  49. + "cmp globals max reversed zip compile hasattr memoryview round __import__"
  50. + "complex hash min set apply delattr help next setattr buffer"
  51. + "dict hex object slice coerce dir id oct sorted intern ";
  52. var pythonBuiltinsL = pythonBuiltins.split(" ").join("() ").split(" ");
  53. var pythonBuiltinsU = pythonBuiltins.toUpperCase().split(" ").join("() ").split(" ");
  54. function getCompletions(token, context) {
  55. var found = [], start = token.string;
  56. function maybeAdd(str) {
  57. if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
  58. }
  59. function gatherCompletions(_obj) {
  60. forEach(pythonBuiltinsL, maybeAdd);
  61. forEach(pythonBuiltinsU, maybeAdd);
  62. forEach(pythonKeywordsL, maybeAdd);
  63. forEach(pythonKeywordsU, maybeAdd);
  64. }
  65. if (context) {
  66. // If this is a property, see if it belongs to some object we can
  67. // find in the current environment.
  68. var obj = context.pop(), base;
  69. if (obj.type == "variable")
  70. base = obj.string;
  71. else if(obj.type == "variable-3")
  72. base = ":" + obj.string;
  73. while (base != null && context.length)
  74. base = base[context.pop().string];
  75. if (base != null) gatherCompletions(base);
  76. }
  77. return found;
  78. }
  79. })();