1''' 2This module contains template variables (added through the templates engine). 3 4Users should be able to create their own templates by adding an additional path in the scripts 5and creating any file that starts with "pytemplate" within that directory. 6 7E.g.: clients could get all the methods in the class and use them to complete the template, make 8custom date formatting, etc (only limited by your imagination as any class from Pydev could be 9imported and used here). 10 11The only annoyance is that changes aren't automatically applied, so, one must (in a Pydev Editor) use: 12 13Ctrl + 2 + --clear-templates-cache 14 15to clear the cache so that any changed files regarding the templates are (re)evaluated (the only 16other way to get the changes applied is restarting eclipse). 17 18The concept is the same as the default scripting engine in pydev. The only difference is that it'll 19only get files starting with 'pytemplate', so, it's also worth checking 20http://pydev.org/manual_articles_scripting.html 21 22context passed as parameter: org.python.pydev.editor.codecompletion.templates.PyDocumentTemplateContext 23''' 24 25import time 26 27import template_helper 28 29if False: 30 #Variables added externally by the runner of this module. 31 py_context_type = org.python.pydev.editor.templates.PyContextType # @UndefinedVariable 32 33 34#=================================================================================================== 35# _CreateSelection 36#=================================================================================================== 37def _CreateSelection(context): 38 ''' 39 Created method so that it can be mocked on tests. 40 ''' 41 selection = context.createPySelection() 42 return selection 43 44#=================================================================================================== 45# _IsGrammar3 46#=================================================================================================== 47def _IsGrammar3(context): 48 if context is None: 49 return False #Default is Python 2 50 from org.python.pydev.core import IGrammarVersionProvider 51 if context.getGrammarVersion() >= IGrammarVersionProvider.GRAMMAR_PYTHON_VERSION_3_0: 52 return True 53 return False 54 55 56#=============================================================================== 57# ISO-8601 Dates 58#=============================================================================== 59def GetISODate(context): 60 return time.strftime("%Y-%m-%d") 61 62template_helper.AddTemplateVariable(py_context_type, 'isodate', 'ISO-8601 Ymd date', GetISODate) 63 64def GetISODateString1(context): 65 return time.strftime("%Y-%m-%d %H:%M") 66 67template_helper.AddTemplateVariable(py_context_type, 'isodatestr', 'ISO-8601 Ymd HM date', GetISODateString1) 68 69def GetISODateString2(context): 70 return time.strftime("%Y-%m-%d %H:%M:%S") 71 72template_helper.AddTemplateVariable(py_context_type, 'isodatestr2', 'ISO-8601 Ymd HMS date', GetISODateString2) 73 74 75#=================================================================================================== 76# GetModuleName 77#=================================================================================================== 78def GetModuleName(context): 79 return context.getModuleName() 80 81template_helper.AddTemplateVariable(py_context_type, 'module', 'Current module', GetModuleName) 82 83 84#=================================================================================================== 85# _GetCurrentASTPath 86#=================================================================================================== 87def _GetCurrentASTPath(context, reverse=False): 88 ''' 89 @return: ArrayList(SimpleNode) 90 ''' 91 FastParser = context.getFastParserClass() # from org.python.pydev.parser.fastparser import FastParser 92 selection = _CreateSelection(context) 93 ret = FastParser.parseToKnowGloballyAccessiblePath( 94 context.getDocument(), selection.getStartLineIndex()) 95 if reverse: 96 from java.util import Collections # @UnresolvedImport 97 Collections.reverse(ret) 98 99 return ret 100 101 102#=================================================================================================== 103# GetQualifiedNameScope 104#=================================================================================================== 105def GetQualifiedNameScope(context): 106 NodeUtils = context.getNodeUtilsClass() # from org.python.pydev.parser.visitors import NodeUtils 107 108 ret = '' 109 for stmt in _GetCurrentASTPath(context): 110 if ret: 111 ret += '.' 112 ret += NodeUtils.getRepresentationString(stmt) 113 return ret 114 115 116template_helper.AddTemplateVariable( 117 py_context_type, 'current_qualified_scope', 'Current qualified scope.', GetQualifiedNameScope) 118 119 120 121#=================================================================================================== 122# _GetCurrentClassStmt 123#=================================================================================================== 124def _GetCurrentClassStmt(context): 125 NodeUtils = context.getNodeUtilsClass() #from org.python.pydev.parser.visitors import NodeUtils 126 ClassDef = context.getClassDefClass() # from org.python.pydev.parser.jython.ast import ClassDef 127 128 for stmt in _GetCurrentASTPath(context, True): 129 if isinstance(stmt, ClassDef): 130 return stmt 131 return None 132 133 134#=================================================================================================== 135# GetCurrentClass 136#=================================================================================================== 137def GetCurrentClass(context): 138 NodeUtils = context.getNodeUtilsClass() #from org.python.pydev.parser.visitors import NodeUtils 139 ClassDef = context.getClassDefClass() # from org.python.pydev.parser.jython.ast import ClassDef 140 141 stmt = _GetCurrentClassStmt(context) 142 if stmt is not None: 143 return NodeUtils.getRepresentationString(stmt) 144 145 return '' 146 147 148template_helper.AddTemplateVariable(py_context_type, 'current_class', 'Current class', GetCurrentClass) 149 150 151#=================================================================================================== 152# GetPydevdFileLocation 153#=================================================================================================== 154def GetPydevdFileLocation(context): 155 from org.python.pydev.debug.ui.launching import PythonRunnerConfig # @UnresolvedImport 156 return PythonRunnerConfig.getDebugScript() 157 158template_helper.AddTemplateVariable( 159 py_context_type, 'pydevd_file_location', 'pydevd.py File Location', GetPydevdFileLocation) 160 161#=================================================================================================== 162# GetPydevdDirLocation 163#=================================================================================================== 164def GetPydevdDirLocation(context): 165 from org.python.pydev.debug.ui.launching import PythonRunnerConfig # @UnresolvedImport 166 import os 167 return os.path.split(PythonRunnerConfig.getDebugScript())[0] 168 169template_helper.AddTemplateVariable( 170 py_context_type, 'pydevd_dir_location', 'pydevd.py Directory Location', GetPydevdDirLocation) 171 172 173 174#=================================================================================================== 175# GetCurrentMethod 176#=================================================================================================== 177def GetCurrentMethod(context): 178 NodeUtils = context.getNodeUtilsClass() #from org.python.pydev.parser.visitors import NodeUtils 179 FunctionDef = context.getFunctionDefClass() # from org.python.pydev.parser.jython.ast import FunctionDef 180 181 for stmt in _GetCurrentASTPath(context, True): 182 if isinstance(stmt, FunctionDef): 183 return NodeUtils.getRepresentationString(stmt) 184 return '' 185 186 187 188template_helper.AddTemplateVariable(py_context_type, 'current_method', 'Current method', GetCurrentMethod) 189 190 191#=================================================================================================== 192# _GetPreviousOrNextClassOrMethod 193#=================================================================================================== 194def _GetPreviousOrNextClassOrMethod(context, searchForward): 195 NodeUtils = context.getNodeUtilsClass() #from org.python.pydev.parser.visitors import NodeUtils 196 FastParser = context.getFastParserClass() #from org.python.pydev.parser.fastparser import FastParser 197 doc = context.getDocument() 198 selection = _CreateSelection(context) 199 startLine = selection.getStartLineIndex() 200 201 found = FastParser.firstClassOrFunction(doc, startLine, searchForward, context.isCythonFile()) 202 if found: 203 return NodeUtils.getRepresentationString(found) 204 return '' 205 206 207 208#=================================================================================================== 209# GetPreviousClassOrMethod 210#=================================================================================================== 211def GetPreviousClassOrMethod(context): 212 return _GetPreviousOrNextClassOrMethod(context, False) 213 214template_helper.AddTemplateVariable( 215 py_context_type, 'prev_class_or_method', 'Previous class or method', GetPreviousClassOrMethod) 216 217#=================================================================================================== 218# GetNextClassOrMethod 219#=================================================================================================== 220def GetNextClassOrMethod(context): 221 return _GetPreviousOrNextClassOrMethod(context, True) 222 223template_helper.AddTemplateVariable( 224 py_context_type, 'next_class_or_method', 'Next class or method', GetNextClassOrMethod) 225 226 227 228#=================================================================================================== 229# GetSuperclass 230#=================================================================================================== 231def GetSuperclass(context): 232 selection = _CreateSelection(context) 233 stmt = _GetCurrentClassStmt(context) 234 BadLocationException = context.getBadLocationExceptionClass() # from org.eclipse.jface.text import BadLocationException 235 if stmt is not None: 236 doc = context.getDocument() 237 name = stmt.name 238 nameStartOffset = selection.getAbsoluteCursorOffset(name.beginLine - 1, name.beginColumn - 1) 239 nameStartOffset += len(name.id) 240 241 found_start = False 242 i = 0 243 contents = '' 244 while True: 245 try: 246 c = doc.get(nameStartOffset + i, 1) 247 i += 1 248 249 if c == '(': 250 found_start = True 251 252 elif c in (')', ':'): 253 break 254 255 elif c in ('\r', '\n', ' ', '\t'): 256 pass 257 258 elif c == '#': #skip comments 259 while c not in ('\r', '\n'): 260 c = doc.get(nameStartOffset + i, 1) 261 i += 1 262 263 264 else: 265 if found_start: 266 contents += c 267 268 except BadLocationException: 269 return '' #Seems the class declaration is not properly finished as we're now out of bounds in the doc. 270 271 if ',' in contents: 272 ret = [] 273 for c in contents.split(','): 274 ret.append(c.strip()) 275 return ret 276 277 return contents.strip() 278 279 return '' 280 281template_helper.AddTemplateVariable( 282 py_context_type, 'superclass', 'Superclass of the current class', GetSuperclass) 283