def reformat(separator, area): separator = window.clipboard_get() if separator_dict.get( separator) == 'clipboard' else separator_dict.get(separator) used_eol = format_types_dict.get(notepad.getFormatType()) editor.beginUndoAction() if area == 0: rows = editor.getCharacterPointer().splitlines() rows = prepare(separator, rows, used_eol) editor.setText(used_eol.join(rows)) elif area == 1: if editor.selectionIsRectangle(): selections = [(editor.getSelectionNStart(i), editor.getSelectionNEnd(i)) for i in range(editor.getSelections())] rows = [ editor.getRangePointer(x, y - x) for x, y in selections ] rows = prepare(separator, rows, used_eol) editor.clearSelections() for i, position in zip(reversed(range(len(selections))), reversed(selections)): editor.setTarget(*position) editor.replaceTarget(rows[i]) else: first_selected_line, last_selected_line = editor.getUserLineSelection( ) startpos = editor.positionFromLine(first_selected_line) endpos = editor.positionFromLine(last_selected_line) rows = editor.getRangePointer(startpos, endpos - startpos) rows = prepare(separator, rows.split(used_eol), used_eol) editor.setTarget(startpos, endpos) editor.replaceTarget(used_eol.join(rows)) else: first_visible_line = editor.getFirstVisibleLine() startpos = editor.positionFromLine(first_visible_line) endpos = editor.positionFromLine(editor.linesOnScreen() + first_visible_line) rows = editor.getRangePointer(startpos, endpos - startpos) rows = prepare(separator, rows.split(used_eol), used_eol) editor.setTarget(startpos, endpos) editor.replaceTarget(used_eol.join(rows)) editor.endUndoAction()
def __format_document(item): new_content = item['newText'] _start_line = item['range']['start']['line'] _start_char_pos = item['range']['start']['character'] _end_line = item['range']['end']['line'] _end_char_pos = item['range']['end']['character'] start = editor.positionFromLine(_start_line) + _start_char_pos end = editor.positionFromLine(_end_line) + _end_char_pos if start == -1 or end == -1: log(f'ABORTED - negative position found:{item}') return editor.setTargetRange(start, end) editor.replaceTarget(new_content)
def _send_document_range_formatting(self): _start_pos = editor.getSelectionStart() start_line = editor.lineFromPosition(_start_pos) start_char_pos = _start_pos - editor.positionFromLine(start_line) _end_pos = editor.getSelectionEnd() end_line = editor.lineFromPosition(_end_pos) end_char_pos = _end_pos - editor.positionFromLine(end_line) self.com_manager.send( self.lsp_msg.rangeFormatting(self.current_file, self._get_file_version(), (start_line, start_char_pos), (end_line, end_char_pos))) self.open_results[ self.lsp_msg.request_id] = self.document_range_formatting_handler
def run(self): line_ending = ['\r\n', '\r', '\n'][notepad.getFormatType()] if editor.getSelectionEmpty(): editor.setText(line_ending.join(self.__sort(editor.getCharacterPointer()))) elif editor.getSelectionMode() == 1: print '-->> {}'.format(editor.getSelectionNStart(0)) start = editor.getSelectionNStart(0) end = editor.getSelectionNEnd(0) start_column = editor.getColumn(start) end_column = editor.getColumn(end) line_start, line_end = editor.getUserLineSelection() start_position_selected_lines = editor.positionFromLine(line_start) end_position_selected_lines = editor.getLineEndPosition(line_end) def sort_as_int_if_possible(text): return int(text.strip()) if text.strip().isdigit() else text if (line_start==0) and (line_end==editor.getLineCount()-1): editor.setText(line_ending.join(self.__sort(editor.getCharacterPointer(),lambda x: sort_as_int_if_possible(x[start_column:end_column])))) else: lines = self.__sort(editor.getTextRange(start_position_selected_lines, end_position_selected_lines), lambda x: sort_as_int_if_possible(x[start_column:end_column])) print line_ending.join(lines) editor.setTarget(start_position_selected_lines, end_position_selected_lines) editor.replaceTarget(line_ending.join(lines)) else: text_of_sel = editor.getTextRange(*editor.getUserCharSelection()) line_end_of_sel = line_ending if text_of_sel.endswith(line_ending) else '' lines = self.__sort(text_of_sel) editor.replaceSel(line_ending.join(lines) + line_end_of_sel) self.window.destroy()
def style(self): ''' Calculates the text area to be searched for in the current document. Calls up the regexes to find the position and calculates the length of the text to be colored. Deletes the old indicators before setting new ones. Args: None Returns: None ''' start_line = editor.docLineFromVisible(editor.getFirstVisibleLine()) end_line = editor.docLineFromVisible(start_line + editor.linesOnScreen()) if editor.getWrapMode(): end_line = sum([editor.wrapCount(x) for x in range(end_line)]) onscreen_start_position = editor.positionFromLine(start_line) onscreen_end_pos = editor.getLineEndPosition(end_line) editor.setIndicatorCurrent(0) editor.indicatorClearRange(0, editor.getTextLength()) for color, regex in self.regexes.items(): editor.research( regex[0], lambda m: self.paint_it( color[1], m.span(regex[1])[0], m.span(regex[1])[1] - m.span(regex[1])[0], onscreen_start_position, onscreen_end_pos), 0, onscreen_start_position, onscreen_end_pos)
def on_char_added(self, args): if self.lsp_doc_flag: if chr(args['ch']) == ')': editor.callTipCancel() elif (args['ch'] in self.current_triggers[ self.current_language]['signatureHelpProvider'] or args['ch'] in self.current_triggers[ self.current_language]['completionProvider']): cur_pos = editor.getCurrentPos() _line = editor.lineFromPosition(cur_pos) _character_pos = cur_pos - editor.positionFromLine(_line) _version = self._set_file_version() self._send_did_change(_version) if args['ch'] in self.current_triggers[ self.current_language]['signatureHelpProvider']: self.com_manager.send( self.lsp_msg.signatureHelp( self.current_file, self.current_language.lower(), _version, editor.getText(), _line, _character_pos)) self.open_results[ self.lsp_msg. request_id] = self.signature_response_handler else: self.com_manager.send( self.lsp_msg.completion( *self.__TextDocumentPositionParams())) self.open_results[ self.lsp_msg. request_id] = self.completion_response_handler
def getUncompleteLine(self, iPos): '''get the whole expression with the context of a variable that is required to evaluate the variable''' iLine = editor.lineFromPosition(iPos) iStart = editor.positionFromLine(iLine) linePart = editor.getTextRange(iStart, iPos - 1) return linePart
def logfile_lexer(self, start_pos, end_pos): ''' Main lexing logic. Gets called by styleneeded callback ''' def style_it(match, STYLE): ''' Inform scintilla to do the styling''' if match[1]-match[0] >= 0: editor.startStyling(start_pos + match[0], 31) editor.setStyling(match[1]-match[0], STYLE) def do_regex(regex): ''' return a list of match positions Note, is using python regular expression instead of boost::re ''' return [m.span(0) for m in re.finditer(regex, text, flags=re.I)] # ensure that position is really the first position for each line start_pos = editor.positionFromLine(editor.lineFromPosition(start_pos)) # fast but potentially unsafe way to get the text of the line text = editor.getRangePointer(start_pos, end_pos-start_pos) # first everything will be styled with default style style_it((start_pos, end_pos), self.DEFAULT) # map style_it function to each match returned by do_regex # ordering is important as it might be that a line matches # multiple regexes - the last do_regex overwrites previous styling map(lambda match: style_it(match, self.WARNING_STYLE), do_regex(self.WARNING_REGEX)) map(lambda match: style_it(match, self.ERROR_STYLE), do_regex(self.ERROR_REGEX)) # this needs to stay and to be the last line, to signal scintilla we are done. editor.startStyling(end_pos,31)
def style(self): line_number = editor.getFirstVisibleLine() start_position = editor.positionFromLine(line_number) end_position = editor.getLineEndPosition(line_number + editor.linesOnScreen()) for indicator, regex in self.regex_dict.items(): self.do_regex(regex, indicator, start_position, end_position)
def reformat(separator,area): separator = window.clipboard_get() if separator_dict.get(separator) == 'clipboard' else separator_dict.get(separator) used_eol = format_types_dict.get(notepad.getFormatType()) editor.beginUndoAction() if area == 0: rows = editor.getCharacterPointer().splitlines() rows = prepare(separator, rows, used_eol) editor.setText(used_eol.join(rows)) elif area == 1: if editor.selectionIsRectangle(): selections = [(editor.getSelectionNStart(i),editor.getSelectionNEnd(i)) for i in range(editor.getSelections())] rows = [editor.getRangePointer(x, y-x) for x,y in selections] rows = prepare(separator, rows, used_eol) editor.clearSelections() for i, position in zip(reversed(range(len(selections))), reversed(selections)): editor.setTarget(*position) editor.replaceTarget(rows[i]) else: first_selected_line, last_selected_line = editor.getUserLineSelection() startpos = editor.positionFromLine(first_selected_line) endpos = editor.positionFromLine(last_selected_line) rows = editor.getRangePointer(startpos, endpos-startpos) rows = prepare(separator, rows.split(used_eol), used_eol) editor.setTarget(startpos, endpos) editor.replaceTarget(used_eol.join(rows)) else: first_visible_line = editor.getFirstVisibleLine() startpos = editor.positionFromLine(first_visible_line) endpos = editor.positionFromLine(editor.linesOnScreen() + first_visible_line) rows = editor.getRangePointer(startpos, endpos-startpos) rows = prepare(separator, rows.split(used_eol), used_eol) editor.setTarget(startpos, endpos) editor.replaceTarget(used_eol.join(rows)) editor.endUndoAction()
def styleneeded_callback(self,args): ''' Called by scintilla to inform the lexer about the need to style the document. If document is of interest call main logic (column_lexer) function Ensures that the start position is really the first position per line ''' if self.is_lexer_doc(): startPos = editor.getEndStyled() lineNumber = editor.lineFromPosition(startPos) startPos = editor.positionFromLine(lineNumber) self.column_lexer(startPos, args['position'])
def styleneeded_callback(self, args): ''' Called by scintilla to inform the lexer about the need to style the document. If document is of interest call main logic (logfile_lexer) function Ensures that the start position is really the first position per line ''' if self.is_lexer_doc(): startPos = editor.getEndStyled() lineNumber = editor.lineFromPosition(startPos) startPos = editor.positionFromLine(lineNumber) self.logfile_lexer(startPos, args['position'])
def paint_it(indicator, pos, length): current_line = editor.lineFromPosition(pos) line_start_position = editor.positionFromLine(current_line) text = editor.getLine(current_line) found_comment_char = text.find('#') relative_line_position = pos - line_start_position if ((-1 < found_comment_char < relative_line_position) or (text.count('"', 0, relative_line_position) % 2 == 1) or (text.count("'", 0, relative_line_position) % 2 == 1)): return else: editor.setIndicatorCurrent(indicator) editor.indicatorFillRange(pos, length)
def rename_response_handler(self, decoded_message): log(decoded_message) # 'result': {'documentChanges': [{'edits': [{'newText': u"...", # 'range': {'end': {'character': 0, 'line': 417}, # 'start': {'character': 0, 'line': 0}}}], # 'textDocument': {'uri': 'file:///d:/...', 'version': None}}]}} if decoded_message['result']: editor.beginUndoAction() for changes in decoded_message['result']['documentChanges']: for change in changes['edits']: _file = url2pathname( changes['textDocument']['uri'].replace('file:', '')) notepad.open(_file) start_line = change['range']['start']['line'] end_line = change['range']['end']['line'] start_position = editor.positionFromLine( start_line) + change['range']['start']['character'] end_position = editor.positionFromLine( end_line) + change['range']['end']['character'] editor.setTargetRange(start_position, end_position) editor.replaceTarget(change['newText']) editor.endUndoAction()
def paint_it(indicator, pos, length): current_line = editor.lineFromPosition(pos) line_start_position = editor.positionFromLine(current_line) text = editor.getLine(current_line) found_comment_char = text.find('#') relative_line_position = pos-line_start_position if((-1 < found_comment_char < relative_line_position) or (text.count('"', 0, relative_line_position) % 2 == 1) or (text.count("'", 0, relative_line_position) % 2 == 1)): return else: editor.setIndicatorCurrent(indicator) editor.indicatorFillRange(pos,length)
def style(self): line_number = editor.getFirstVisibleLine() start_position = editor.positionFromLine(line_number) end_position = editor.getLineEndPosition(line_number + editor.linesOnScreen()) editor.setIndicatorCurrent(self.indicator) editor.indicatorClearRange(start_position, end_position - start_position) flag = 0 editor.research( '^# ?%%(.*)$', lambda m: self.paint_it(self.indicator, m.span(flag)[0], m.span(flag)[1] - m.span(flag)[0]), 0, start_position, end_position)
def run(self): line_ending = ['\r\n', '\r', '\n'][notepad.getFormatType()] if editor.getSelectionEmpty(): editor.setText( line_ending.join(self.__sort(editor.getCharacterPointer()))) elif editor.getSelectionMode() == 1: print '-->> {}'.format(editor.getSelectionNStart(0)) start = editor.getSelectionNStart(0) end = editor.getSelectionNEnd(0) start_column = editor.getColumn(start) end_column = editor.getColumn(end) line_start, line_end = editor.getUserLineSelection() start_position_selected_lines = editor.positionFromLine(line_start) end_position_selected_lines = editor.getLineEndPosition(line_end) def sort_as_int_if_possible(text): return int(text.strip()) if text.strip().isdigit() else text if (line_start == 0) and (line_end == editor.getLineCount() - 1): editor.setText( line_ending.join( self.__sort( editor.getCharacterPointer(), lambda x: sort_as_int_if_possible(x[start_column: end_column])))) else: lines = self.__sort( editor.getTextRange(start_position_selected_lines, end_position_selected_lines), lambda x: sort_as_int_if_possible(x[start_column:end_column])) print line_ending.join(lines) editor.setTarget(start_position_selected_lines, end_position_selected_lines) editor.replaceTarget(line_ending.join(lines)) else: text_of_sel = editor.getTextRange(*editor.getUserCharSelection()) line_end_of_sel = line_ending if text_of_sel.endswith( line_ending) else '' lines = self.__sort(text_of_sel) editor.replaceSel(line_ending.join(lines) + line_end_of_sel) self.window.destroy()
def logfile_lexer(self, start_pos, end_pos): ''' Main lexing logic. Gets called by styleneeded callback ''' def style_it(match, STYLE): ''' Inform scintilla to do the styling''' if match[1] - match[0] >= 0: editor.startStyling(start_pos + match[0], 31) editor.setStyling(match[1] - match[0], STYLE) def do_regex(regex): ''' return a list of match positions Note, is using python regular expression instead of boost::re ''' return [ m.span(0) for m in re.finditer(regex, text, flags=re.I) ] # ensure that position is really the first position for each line start_pos = editor.positionFromLine( editor.lineFromPosition(start_pos)) # fast but potentially unsafe way to get the text of the line text = editor.getRangePointer(start_pos, end_pos - start_pos) # first everything will be styled with default style style_it((start_pos, end_pos), self.DEFAULT) # map style_it function to each match returned by do_regex # ordering is important as it might be that a line matches # multiple regexes - the last do_regex overwrites previous styling map(lambda match: style_it(match, self.WARNING_STYLE), do_regex(self.WARNING_REGEX)) map(lambda match: style_it(match, self.ERROR_STYLE), do_regex(self.ERROR_REGEX)) # this needs to stay and to be the last line, to signal scintilla we are done. editor.startStyling(end_pos, 31)
def column_lexer(self, start_pos, end_pos): ''' Main lexing logic. Gets called by styleneeded callback ''' def style_it(start, length, STYLE): ''' Inform scintilla to do the styling''' if length >= 0: editor.startStyling(start, 31) editor.setStyling(length, STYLE) # first everything will be styled with default style style_it(start_pos, end_pos-start_pos, self.DEFAULT) # loop over line indexes from start_pos and end_pos for line in range(editor.lineFromPosition(start_pos), editor.lineFromPosition(end_pos)): # get start position for each line line_start_pos = editor.positionFromLine(line) # split current line into columns columns = editor.getLine(line).split(self.COLUMN_SEPARATOR) if columns > 0: # iterate over all columns for i, column in enumerate(columns): # get the width of the current column col_length = len(column) if i % 2 == 0: # even column style_it(line_start_pos,col_length,self.EVEN_COLUMN_STYLE) else: # odd column style_it(line_start_pos,col_length, self.ODD_COLUMN_STYLE) # recalculate start position for next column line_start_pos += col_length+1 # this needs to stay and to be the last line, to signal scintilla we are done. editor.startStyling(end_pos,31)
def showCalltip(self, pos=None): iStart = editor.getSelectionStart() iEnd = editor.getSelectionEnd() if pos is None: pos = editor.getCurrentPos() CT_unselected = True CT_expression = True else: CT_unselected = self.popupForUnselectedVariable CT_expression = self.popupForSelectedExpression if iEnd != iStart and iStart <= pos <= iEnd: if CT_expression and iEnd - iStart > 1: expression = editor.getTextRange(iStart, iEnd) if expression == 'False': self.activeCalltip = False editor.callTipShow(iStart, 'set to True') elif expression == 'True': self.activeCalltip = True editor.callTipShow(iStart, 'set to False') elif not '\n' in expression: ret = self.interp.getCallTip(None, expression) if ret and (CT_unselected or ret[-1] != 'value error'): element, nHighlight, calltip = ret self.activeCalltip = 'doc' editor.callTipShow(iStart, ''.join(calltip)) editor.callTipSetHlt(0, int(nHighlight)) else: iLineStart = editor.positionFromLine( editor.lineFromPosition(iStart)) var = editor.getTextRange(iStart, iEnd) line = editor.getTextRange(iLineStart, iEnd) if var == '.': autoCompleteList = self.interp.autoCompleteObject( self.getUncompleteLine(iStart + 1)) if autoCompleteList: editor.autoCSetSeparator(ord('\t')) editor.autoCSetIgnoreCase(False) editor.autoCSetCaseInsensitiveBehaviour(False) editor.autoCSetOrder(0) editor.autoCSetDropRestOfWord(True) editor.autoCShow(0, autoCompleteList) else: ret = self.interp.getCallTip(line, var) if ret: element, nHighlight, calltip = ret if element == var == 'False': self.activeCalltip = False editor.callTipShow(iStart, 'set to True') elif element == var == 'True': self.activeCalltip = True editor.callTipShow(iStart, 'set to False') elif ret[-1] != 'value error': self.activeCalltip = 'doc' editor.callTipShow(iStart, ''.join(calltip)) editor.callTipSetHlt(0, int(nHighlight)) elif CT_unselected and iStart == iEnd and pos >= 0: iLine = editor.lineFromPosition(pos) line = editor.getLine(iLine) iLineStart = editor.positionFromLine(iLine) posInLine = pos - iLineStart iWordEnd = 0 for iWordStart in range(posInLine, -1, -1): s = line[iWordStart] if not ('a' <= s <= 'z' or 'A' <= s <= 'Z' or '0' <= s <= '9' or s == '_'): iWordStart += 1 break if iWordStart <= posInLine: for iWordEnd in range(posInLine + 1, len(line)): s = line[iWordEnd] if not ('a' <= s <= 'z' or 'A' <= s <= 'Z' or '0' <= s <= '9' or s == '_'): iWordEnd -= 1 break var = line[iWordStart:iWordEnd + 1] if var: var = line[iWordStart:iWordEnd + 1] ret = self.interp.getCallTip(line[0:iWordEnd + 1], var) pos = iLineStart + iWordStart if ret: element, nHighlight, calltip = ret if calltip != 'value error': self.activeCalltip = 'doc' editor.callTipShow(pos, ''.join(calltip)) editor.callTipSetHlt(0, int(nHighlight))
def runThread(self, moveCursor=True, nonSelectedLine=None, onlyInsideCodeLines=False): '''Executes the smallest possible code element for the current selection. Or execute one marked cell.''' bufferID = notepad.getCurrentBufferID() self.bufferActive = bufferID lang = notepad.getLangType() filename = notepad.getCurrentFilename() if lang == Npp.LANGTYPE.TXT and '.' not in os.path.basename(filename): notepad.setLangType(Npp.LANGTYPE.PYTHON) elif lang != Npp.LANGTYPE.PYTHON: self.bufferActive = 0 return if nonSelectedLine is None: iSelStart = editor.getSelectionStart() iSelEnd = editor.getSelectionEnd() iPos = editor.getCurrentPos() iLineCursor = iLineStart = editor.lineFromPosition(iSelStart) iLineEnd = max(iLineStart, editor.lineFromPosition(iSelEnd - 1)) else: iLineCursor = iLineStart = iLineEnd = nonSelectedLine iSelStart = iSelEnd = 0 selection = iSelStart != iSelEnd startLine = editor.getLine(iLineStart).rstrip() cellMode = not selection and (startLine.startswith('#%%') or startLine.startswith('# %%')) err = None if not cellMode: getLineEnd = self.completeBlockEnd(iLineStart, iLineMin=iLineEnd, iLineMax=editor.getLineCount() - 1) iFirstCodeLine, iLineEnd, isEmpty, inspectLineBefore = next( getLineEnd) if not inspectLineBefore and iFirstCodeLine: iLineStart = iFirstCodeLine if isEmpty: self.hideMarkers(bufferID) self.bufferActive = 0 return iLineStart = self.completeBlockStart(iLineStart, inspectLineBefore) requireMore = True iStart = editor.positionFromLine(iLineStart) iDocEnd = editor.getLength() if cellMode: iMatch = [] editor.research('^# ?%%(.*)$', lambda m: iMatch.append(m.span(0)[0] - 1), 0, iStart + 4, iDocEnd - 1, 1) iEnd = iMatch[0] if len(iMatch) else iDocEnd iLineEnd = editor.lineFromPosition(iEnd) block = editor.getTextRange(iStart, iEnd).rstrip() r = self.interp.tryCode(iLineStart, filename, block) if r is None: self.hideMarkers(bufferID) self.bufferActive = 0 return err, requireMore, isValue = r if requireMore: err = True else: # add more lines until the parser is happy or finds # a syntax error while requireMore: iEnd = editor.getLineEndPosition(iLineEnd) block = editor.getTextRange(iStart, iEnd).rstrip() if block: res = self.interp.tryCode(iLineStart, filename, block) if res is None: self.bufferActive = 0 return else: err, requireMore, isValue = res else: err, requireMore, isValue = None, True, False if requireMore: nextLine = next(getLineEnd, None) if nextLine is None: self.bufferActive = 0 iEnd = editor.getLength() block = editor.getTextRange(iStart, iEnd).rstrip() err, buff = self.interp.execute( block, iLineStart, filename) self.outBuffer(buff) self.setMarkers(iLineStart, iLineEnd, block, iMarker=self.m_error, bufferID=bufferID) return iCodeLineStart, iLineEnd, isEmpty, inspectLineBefore = nextLine if onlyInsideCodeLines and not selection and not iLineStart <= iLineCursor <= iLineEnd: self.hideMarkers() self.bufferActive = 0 return if self.activeCalltip: editor.callTipCancel() self.activeCalltip = None self.setMarkers(iLineStart, iLineEnd, block, iMarker=(self.m_active if not err else self.m_error), bufferID=bufferID) if err is not None: if moveCursor: editor.setSelectionStart(iStart) editor.scrollRange(iEnd, iStart) if err is not True: self.outBuffer(err) else: # Check if correct path is set if self.lastActiveBufferID != bufferID and '.' in os.path.basename( filename): filePath = os.path.normpath(os.path.split(filename)[0]) self.interp.execute('os.chdir(' + repr(filePath) + ')') self.lastActiveBufferID = bufferID # Start a thread to execute the code if moveCursor: iNewPos = max(iPos, editor.positionFromLine(iLineEnd + 1)) editor.setSelectionStart(iNewPos) editor.setCurrentPos(iNewPos) if iNewPos >= iDocEnd and iLineEnd == editor.getLineCount( ) - 1: editor.newLine() editor.scrollCaret() if self.matplotlib_eventHandler and not self.matplotlib_enabled: if 'matplotlib' in block: self.interp.execute(init_matplotlib_eventHandler) self.matplotlib_enabled = True if isValue: res = self.interp.evaluate() if res is not None: err, result = res if not err: if self.bufferActive: self.changeMarkers(iMarker=self.m_finish, bufferID=bufferID) if result: self.stdout(result + '\n') else: self.changeMarkers(iMarker=self.m_error, bufferID=bufferID) self.outBuffer(result) else: res = self.interp.execute() if res is not None: err, result = res if not err and self.bufferActive: self.changeMarkers(iMarker=self.m_finish, bufferID=bufferID) else: self.changeMarkers(iMarker=self.m_error, bufferID=bufferID) self.outBuffer(result) if err: self.changeMarkers(iMarker=self.m_error, bufferID=bufferID) self.bufferActive = 0
def onMouseDwell(self, args): '''Show a call tip window about the current content of a selected variable''' if self.bufferBusy or self.interp.kernelBusy.isSet(): return if editor.callTipActive(): return p = editor.positionFromPoint(args['x'], args['y']) iStart = editor.getSelectionStart() iEnd = editor.getSelectionEnd() if iEnd != iStart and iStart <= p <= iEnd: if self.popupForSelectedExpression and iEnd - iStart > 1: expression = editor.getTextRange(iStart, iEnd) if expression == 'False': self.activeCalltip = False editor.callTipShow(iStart, 'set to True') elif expression == 'True': self.activeCalltip = True editor.callTipShow(iStart, 'set to False') elif not '\n' in expression: ret = self.interp.getCallTip(None, expression) if ret: element, nHighlight, calltip = ret self.activeCalltip = 'doc' editor.callTipShow(iStart, ''.join(calltip)) editor.callTipSetHlt(0, int(nHighlight)) else: iLineStart = editor.positionFromLine( editor.lineFromPosition(iStart)) var = editor.getTextRange(iStart, iEnd) line = editor.getTextRange(iLineStart, iEnd) if var == '.': autoCompleteList = self.interp.autoCompleteObject( self.getUncompleteLine(iStart + 1)) if autoCompleteList: editor.autoCSetSeparator(ord('\t')) editor.autoCSetIgnoreCase(False) editor.autoCSetCaseInsensitiveBehaviour(False) editor.autoCSetOrder(0) editor.autoCSetDropRestOfWord(True) editor.autoCShow(0, autoCompleteList) else: ret = self.interp.getCallTip(line, var) if ret: element, nHighlight, calltip = ret if element == var == 'False': self.activeCalltip = False editor.callTipShow(iStart, 'set to True') elif element == var == 'True': self.activeCalltip = True editor.callTipShow(iStart, 'set to False') else: self.activeCalltip = 'doc' editor.callTipShow(iStart, ''.join(calltip)) editor.callTipSetHlt(0, int(nHighlight)) elif self.popupForUnselectedVariable and iStart == iEnd and p >= 0: iLine = editor.lineFromPosition(p) line = editor.getLine(iLine) iLineStart = editor.positionFromLine(iLine) posInLine = p - iLineStart iWordEnd = 0 for iWordStart in range(posInLine, -1, -1): s = line[iWordStart] if not ('a' <= s <= 'z' or 'A' <= s <= 'Z' or '0' <= s <= '9' or s == '_'): iWordStart += 1 break if iWordStart <= posInLine: for iWordEnd in range(posInLine + 1, len(line)): s = line[iWordEnd] if not ('a' <= s <= 'z' or 'A' <= s <= 'Z' or '0' <= s <= '9' or s == '_'): iWordEnd -= 1 break var = line[iWordStart:iWordEnd + 1] if var: var = line[iWordStart:iWordEnd + 1] ret = self.interp.getCallTip(line[0:iWordEnd + 1], var) pos = iLineStart + iWordStart if ret: element, nHighlight, calltip = ret self.activeCalltip = 'doc' editor.callTipShow(pos, ''.join(calltip)) editor.callTipSetHlt(0, int(nHighlight))