Created
November 8, 2013 04:32
-
-
Save cgreer/7366297 to your computer and use it in GitHub Desktop.
Get the tag (function/method/etc) in which the current position (cursor, file row/col) is in that tag's scope.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import re | |
| def first_non_whitespace_index(lineText): | |
| ''' Find the index of the first non-whitespace character on line. ''' | |
| pat = re.compile(r'(\s*)(\S)') | |
| m = pat.match(lineText) | |
| if m: | |
| # start(2) gets start of 2nd group | |
| return m.start(2) | |
| else: | |
| return None | |
| def is_comment_line(lineText): | |
| ''' Is line just whitespace followed by comments? ''' | |
| pat = re.compile(r'\s*(#|\'\'\'|\"\"\")') | |
| return bool(pat.match(lineText)) | |
| def is_blank_line(lineText): | |
| ''' Is line only whitespace? ''' | |
| pat = re.compile(r'\s*\n') | |
| m = pat.match(lineText) | |
| return bool(m) | |
| def py_get_nearest_tag(fileText, lineNum, byteNum): | |
| ''' Cursor is in tag's scope. Which tag? | |
| lineNum input is 1-based | |
| byteNum input is 0-based | |
| ''' | |
| # Get lines but preserve newlines | |
| fileLines = fileText.split("\n") | |
| fileLines = ["%s\n" % x for x in fileLines] | |
| fxnDefPattern = re.compile(r'^(\s*)(def\s+\S+)\(', re.MULTILINE) | |
| currLine = lineNum - 1 | |
| currByte = byteNum | |
| while True: | |
| # Get left most non-whitespace character | |
| # Don't change the currByte if only whitespace or comments | |
| lineText = fileLines[currLine] | |
| # Move to the next line | |
| m = fxnDefPattern.match(lineText) | |
| if m: | |
| if m.start(2) < currByte: | |
| logging.debug( m.group(2)) | |
| return (currLine + 1, m.group(2)) | |
| # Check if non-coding line (blank or comment-only line) | |
| if is_comment_line(lineText) or is_blank_line(lineText): | |
| if currLine == 0: | |
| return None | |
| currLine -= 1 | |
| continue | |
| # Move to first coding character on line | |
| # Only move if fnwi is less indented than the current position | |
| fnwi = first_non_whitespace_index(lineText) | |
| currByte = fnwi if (fnwi < currByte) else currByte | |
| if currByte == None: | |
| raise ValueError("Can't find coding byte on line") | |
| if currLine == 0: | |
| return None | |
| currLine -= 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment