def start_regex_tester(): if REGEX_TESTER_FILE_NAME == '': notepad.messageBox('You need to indicate, in the REGEX_TESTER_FILE_NAME variable,\n' + 'the fully qualified file name of the TEXT file containing ' + 'the REGEX(ES) to test', 'REGEX_TESTER_FILE_NAME is not set') return False current_document = 0 if notepad.getCurrentView() == 1 else notepad.getCurrentBufferID() global REGEX_TESTER_INPUT_TAB REGEX_TESTER_INPUT_TAB = regex_tester_doc_already_exists() if REGEX_TESTER_INPUT_TAB == 0 : notepad.open(REGEX_TESTER_FILE_NAME) if notepad.getCurrentFilename().upper() == REGEX_TESTER_FILE_NAME.upper(): REGEX_TESTER_INPUT_TAB = notepad.getCurrentBufferID() else: notepad.messageBox('Could not open specified file\n' + '{0}'.format(REGEX_TESTER_FILE_NAME), 'Regex Tester Startup Failed', 0) return False else: notepad.activateBufferID(REGEX_TESTER_INPUT_TAB) if notepad.getCurrentView() != 1: notepad.menuCommand(MENUCOMMAND.VIEW_GOTO_ANOTHER_VIEW) STATUS_LINE = 'RegexTester isActive [] flags:sitpr' current_status_line = editor2.getLine(0) if 'RegexTester' in current_status_line: editor2.replace('RegexTester inActive', 'RegexTester isActive') else: editor2.insertText(0, STATUS_LINE) global REGEX_TESTER_IS_RUNNING REGEX_TESTER_IS_RUNNING = True color_regex_tester_status() set_current_buffer_id() global PREVIOUS_REGEX PREVIOUS_REGEX[CURRENT_BUFFER_ID] = '' editor.callbackSync(regex_tester_updateui_callback, [SCINTILLANOTIFICATION.UPDATEUI]) if current_document != 0: notepad.activateBufferID(current_document) editor2.setFocus(True) editor2.gotoLine(0) notepad.save() notepad.callback(regex_tester_file_before_close_callback, [NOTIFICATION.FILEBEFORECLOSE]) notepad.callback(regex_tester_buffer_activated_callback, [NOTIFICATION.BUFFERACTIVATED]) return True
def setMarkers(self, iLineStart, iLineEnd, block=None, iMarker=None, bufferID=None, startAnimation=True): '''Set markers at the beginning and end of the executed code block, to show the user which part is actually executed and if the code is still running or finished or if errors occurred.''' if block: lineHasCode = [ len(line) > 0 and not (line.isspace() or line.startswith('#')) for line in block.splitlines() ] linesWithCode = [i for i, c in enumerate(lineHasCode) if c] iLineEnd = iLineStart + linesWithCode[-1] iLineStart = iLineStart + linesWithCode[0] nMarkedLines = iLineEnd - iLineStart + 1 markerIDs = [] if bufferID is None: bufferID = notepad.getCurrentBufferID() self.hideMarkers(bufferID) if nMarkedLines <= 4: for iLine in range(nMarkedLines): markerIDs.append(editor.markerAdd(iLineStart + iLine, iMarker)) else: markerIDs.append(editor.markerAdd(iLineStart, iMarker)) markerIDs.append(editor.markerAdd(iLineStart + 1, iMarker + 1)) markerIDs.append(editor.markerAdd(iLineEnd, iMarker)) markerIDs.append(editor.markerAdd(iLineEnd - 1, iMarker + 2)) self.markers[bufferID] = markerIDs if startAnimation and iMarker == self.m_active: self.onMarkerTimer(init=True)
def textModified(self, args): '''When the marked text is modified the execution markers will be hidden, except when the code is still running.''' if args['text'] != '': bufferID = notepad.getCurrentBufferID() if self.markers.get( bufferID, None) is not None and not self.bufferActive and len( self.markers[bufferID]) > 0: iCurrentLine = editor.lineFromPosition(editor.getCurrentPos()) iLines = [] for i in self.markers[bufferID]: iLine = editor.markerLineFromHandle(i) iLines.append(iLine) if min(iLines) <= iCurrentLine <= max(iLines): self.hideMarkers(bufferID) if self.markers.get( bufferID, None) is not None and self.bufferActive and len( self.markers[bufferID]) > 0: iCurrentLine = editor.lineFromPosition(editor.getCurrentPos()) iLines = [] for i in self.markers[bufferID]: iLine = editor.markerLineFromHandle(i) iLines.append(iLine) if len(iLines) > 0 and min(iLines) <= iCurrentLine <= max( iLines): self.setMarkers(min(iLines), max(iLines), iMarker=self.m_active, bufferID=bufferID, startAnimation=False)
def changeMarkers(self, iMarker, bufferID=None): if bufferID != notepad.getCurrentBufferID(): self.bufferMarkerAction[bufferID] = iMarker return iLines = [] for i in self.markers[bufferID]: iLine = editor.markerLineFromHandle(i) #if iLine == -1: # notepad.activateBufferID(bufferID) # iLine = editor.markerLineFromHandle(i) iLines.append(iLine) if iLines: self.setMarkers(min(iLines), max(iLines), iMarker=iMarker, bufferID=bufferID)
def start(config_file=None): ''' Starts the notepad++ lsp client implementation and configures the logging behavior Args: config_file: expected full path to the config file which must be a valid json file the specification of the file must meet the requirements as shown below Returns: True Raises: file error if config_file cannot be found or is invalid config_file format must be at least like this, if one of these keys is missing it is treated as invalid format { "version": "0.3", "loglevel": "info", "logpath": "C:\\temp\\npplsplog.txt", "lspservers": [ { "PYTHON": { "pipe": "tcp", "tcpretries" : 3, "executable": "C:\\Python\\Python38_64\\Scripts\\pyls.exe", "args": ["--tcp", "--check-parent-process", "--log-file", "C:\\temp\\log.txt", "-v"] } }, { "RUST": { "pipe": "io", "executable": "C:\\Users\\USERNAME\\.cargo\\bin\\rls.exe" } }, { "TEMPLATE_IO": { "pipe": "io", "executable": "SOMEDRIVE:\\SOMEPATH\\SOME.exe", "args": ["empty, string or comma delimited strings"] } }, { "TEMPLATE_TCP": { "pipe": "tcp", "port": 2087, "tcpretries" : 3, "executable": "SOMEDRIVE:\\SOMEPATH\\SOME.exe", "args": ["empty, string or comma delimited strings"] } } ] } ''' global single_instance if config_file is None: raise ValueError('start method is missing config_file parameter') else: config = __check_config(config_file) if config: lsp_server_config = __check_lsp_server_config(config['lspservers']) if lsp_server_config: logging.basicConfig( filename=config['logpath'], level={ 'notset': logging.NOTSET, 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'fatal': logging.FATAL, 'critical': logging.CRITICAL, }.get(config['loglevel'], 'notset'), format= '[%(asctime)-15s] [%(thread)-5d] [%(levelname)-10s] %(funcName)-20s %(message)s' ) logging.info(config) if logging.root.level == logging.NOTSET: logging.disable() single_instance = LSPCLIENT(lsp_server_config) args = {'bufferID': notepad.getCurrentBufferID()} single_instance.on_buffer_activated(args) else: notepad.messageBox( 'There seems to be an issue with the configuration file!', 'LSP start error')
def hideMarkers(self, bufferID=None): '''Hide all markers of the current buffer ID.''' if bufferID is None: bufferID = notepad.getCurrentBufferID() markers = self.markers.get(bufferID, []) while markers: editor.markerDeleteHandle(markers.pop())
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 regex_tester_doc_is_current_doc(): return REGEX_TESTER_INPUT_TAB == notepad.getCurrentBufferID()