def getCommandList(): '''Return list of all command modules in leo/commands.''' pattern = g.os_path_finalize_join('.', 'leo', 'commands', '*.py') return sorted([ g.shortFileName(fn) for fn in glob.glob(pattern) if g.shortFileName(fn) != '__init__.py'])
def run(self, files): """Process all files""" self.files = files t1 = time.clock() for fn in files: s, e = g.readFileIntoString(fn) if s: self.tot_s += len(s) g.trace("%8s %s" % ("{:,}".format(len(s)), g.shortFileName(fn))) # Print len(s), with commas. # Fast, accurate: # 1.9 sec for parsing. # 2.5 sec for Null AstFullTraverer traversal. # 2.7 sec to generate all strings. # 3.8 sec to generate all reports. s1 = g.toEncodedString(s) self.tot_lines += len(g.splitLines(s)) # Adds less than 0.1 sec. node = ast.parse(s1, filename="before", mode="exec") ShowDataTraverser(self, fn).visit(node) # elif 0: # Too slow, too clumsy: 3.3 sec for tokenizing # readlines = g.ReadLinesClass(s).next # for token5tuple in tokenize.generate_tokens(readlines): # pass # else: # Inaccurate. 2.2 sec to generate all reports. # self.scan(fn, s) else: g.trace("skipped", g.shortFileName(fn)) t2 = time.clock() # Get the time exlusive of print time. self.show_results() g.trace("done: %4.1f sec." % (t2 - t1))
def create_file_node(self, diff_list, fn1, fn2): '''Create an organizer node for the file.''' p = self.root.insertAsLastChild() p.h = '%s, %s' % (g.shortFileName(fn1).strip(), g.shortFileName(fn2).strip()) p.b = ''.join(diff_list) return p
def run(fn, verbose): '''Run pylint on fn.''' trace = False and not g.unitTesting # theDir is empty for the -f option. from pylint import lint assert lint rc_fn = os.path.abspath(os.path.join('leo', 'test', 'pylint-leo-rc.txt')) if not os.path.exists(rc_fn): print('pylint rc file not found: %s' % (rc_fn)) return if verbose: path = g.os_path_dirname(fn) dirs = path.split(os.sep) theDir = dirs and dirs[-1] or '' print('pylint-leo.py: %s%s%s' % (theDir, os.sep, g.shortFileName(fn))) # Call pylint in a subprocess so Pylint doesn't abort *this* process. args = ','.join([ "fn=r'%s'" % (fn), "rc=r'%s'" % (rc_fn), ]) if 0: # Prints error number. args.append( '--msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}') command = '%s -c "import leo.core.leoGlobals as g; g.run_pylint(%s)"' % ( sys.executable, args) t1 = time.clock() g.execute_shell_commands(command) t2 = time.clock() if trace: g.trace('%4.2f %s' % (t2 - t1, g.shortFileName(fn)))
def start_process(self, c, command, kind, fn=None, shell=False): '''Start or queue a process described by command and fn.''' trace = False and not g.unitTesting self.data = data = self.ProcessData(c, kind, fn, shell) if self.pid: # A process is already active. Add a new callback. if trace: self.put_log('===== Adding callback for %s' % g.shortFileName(fn)) def callback(data=data): fn = data.fn self.put_log('%s: %s' % (kind, g.shortFileName(fn))) self.pid = subprocess.Popen( command, shell=shell, stderr=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True, ) if trace: self.put_log('===== Starting: %s for %s' % ( id(self.pid), g.shortFileName(fn))) data.callback = callback self.process_queue.append(data) else: # Start the process immediately. self.put_log('%s: %s' % (kind, g.shortFileName(fn))) self.pid = subprocess.Popen( command, shell=shell, stderr=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True, ) if trace: self.put_log('===== Starting: %s for %s' % ( id(self.pid), g.shortFileName(fn)))
def getCommandList(): '''Return list of all command modules in leo/commands.''' pattern = g.os_path_finalize_join('.', 'leo', 'commands', '*.py') return sorted([ g.shortFileName(fn) for fn in glob.glob(pattern) if g.shortFileName(fn) != '__init__.py' ])
def run(fn, verbose): '''Run pylint on fn.''' trace = False and not g.unitTesting # theDir is empty for the -f option. from pylint import lint assert lint rc_fn = os.path.abspath(os.path.join('leo','test','pylint-leo-rc.txt')) if not os.path.exists(rc_fn): print('pylint rc file not found: %s' % (rc_fn)) return if verbose: path = g.os_path_dirname(fn) dirs = path.split(os.sep) theDir = dirs and dirs[-1] or '' print('pylint-leo.py: %s%s%s' % (theDir,os.sep,g.shortFileName(fn))) # Call pylint in a subprocess so Pylint doesn't abort *this* process. args = ','.join([ "fn=r'%s'" % (fn), "rc=r'%s'" % (rc_fn), ]) if 0: # Prints error number. args.append('--msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}') command = '%s -c "import leo.core.leoGlobals as g; g.run_pylint(%s)"' % ( sys.executable, args) t1 = time.clock() g.execute_shell_commands(command) t2 = time.clock() if trace: g.trace('%4.2f %s' % (t2-t1, g.shortFileName(fn)))
def run(self, files): '''Process all files''' self.files = files t1 = time.clock() for fn in files: s, e = g.readFileIntoString(fn) if s: self.tot_s += len(s) g.trace('%8s %s' % ("{:,}".format(len(s)), g.shortFileName(fn))) # Print len(s), with commas. # Fast, accurate: # 1.9 sec for parsing. # 2.5 sec for Null AstFullTraverer traversal. # 2.7 sec to generate all strings. # 3.8 sec to generate all reports. s1 = g.toEncodedString(s) self.tot_lines += len(g.splitLines(s)) # Adds less than 0.1 sec. node = ast.parse(s1, filename='before', mode='exec') ShowDataTraverser(self, fn).visit(node) # elif 0: # Too slow, too clumsy: 3.3 sec for tokenizing # readlines = g.ReadLinesClass(s).next # for token5tuple in tokenize.generate_tokens(readlines): # pass # else: # Inaccurate. 2.2 sec to generate all reports. # self.scan(fn, s) else: g.trace('skipped', g.shortFileName(fn)) t2 = time.clock() # Get the time exlusive of print time. self.show_results() g.trace('done: %4.1f sec.' % (t2 - t1))
def getGuiPluginsList(): pattern = g.os_path_finalize_join(".", "leo", "plugins", "qt_*.py") aList = [g.shortFileName(fn) for fn in glob.glob(pattern) if g.shortFileName(fn) != "__init__.py"] aList.extend(["free_layout", "nested_splitter"]) if "qt_main.py" in aList: # Auto-generated file. aList.remove("qt_main.py") return sorted(aList)
def createScriptsMenu (tag,keywords): c = keywords.get("c") path = os.path.join(g.app.loadDir,"..","scripts") if os.path.exists(path): # Create lists of scripts and subdirectories. entries = glob.glob(os.path.join(path,"*")) top_scripts = glob.glob(os.path.join(path,"*.py")) dirs = [f for f in entries if os.path.isdir(f)] #@+<< Return if no scripts exist anywhere >> #@+node:EKR.20040517080555.38: *3* << Return if no scripts exist anywhere >> if not top_scripts: found = False for dir in dirs: scripts = glob.glob(os.path.join(dir,"*.py")) if scripts: found = True ; break if not found: return #@-<< Return if no scripts exist anywhere >> scriptsMenu = c.frame.menu.createNewMenu("&Scripts") table = [] #@+<< Create top-level entries for every script in top_scripts >> #@+node:EKR.20040517080555.39: *3* << Create top-level entries for every script in top_scripts >> table = [] top_scripts.sort() for script in top_scripts: name = g.shortFileName(script) def doScript(event=None,name=name): g.executeScript(name) table.append((name,None,doScript),) c.frame.menu.createMenuEntries(scriptsMenu, table,dynamicMenu=True) #@-<< Create top-level entries for every script in top_scripts >> for dir in dirs: files = glob.glob(os.path.join(dir,"*.py")) if files: #@+<< Create a submenu for dir containing each file in files >> #@+node:EKR.20040517080555.40: *3* << Create a submenu for dir containing each file in files >> # Create the submenu. name = os.path.join("scripts",g.shortFileName(dir)) menu = c.frame.menu.createNewMenu(name,"&Scripts") # Populate the submenu. table = [] for file in files: name = g.shortFileName(file) # EKR: use doScript1 to keep pylint happy. def doScript1(event=None,name=name): g.executeScript(name) table.append((name,None,doScript1),) c.frame.menu.createMenuEntries(menu, table,dynamicMenu=True)
def __init__(self, controller, fn): '''Ctor for ShopDataTraverser class.''' module_tuple = g.shortFileName(fn), 'module', g.shortFileName(fn) # fn, kind, s. self.context_stack = [module_tuple] self.controller = controller self.fn = g.shortFileName(fn) self.formatter = leoAst.AstFormatter() # leoAst.AstPatternFormatter() self.trace = False
def __init__(self, controller, fn): """Ctor for ShopDataTraverser class.""" module_tuple = g.shortFileName(fn), "module", g.shortFileName(fn) # fn, kind, s. self.context_stack = [module_tuple] self.controller = controller self.fn = g.shortFileName(fn) self.formatter = leoAst.AstFormatter() # leoAst.AstPatternFormatter() self.trace = False
def find_c(self, path): '''Return the commander associated with path, or None.''' g = self.g self.update() path = g.os_path_normcase(path) short_path = g.shortFileName(path) for c in self.commanders_list: fn = g.os_path_normcase(c.fileName()) short_fn = g.shortFileName(fn) if fn == path or short_fn == short_path: return c
def getCoreList(): pattern = g.os_path_finalize_join('.','leo','core','leo*.py') aList = [ g.shortFileName(fn) for fn in glob.glob(pattern) if g.shortFileName(fn) != '__init__.py'] aList.extend([ 'runLeo.py', ]) return sorted(aList)
def find_c(self,path): '''Return the commander associated with path, or None.''' g = self.g self.update() path = g.os_path_normcase(path) short_path = g.shortFileName(path) for c in self.commanders_list: fn = g.os_path_normcase(c.fileName()) short_fn = g.shortFileName(fn) if fn == path or short_fn == short_path: return c
def getCoreList(): pattern = g.os_path_finalize_join('.', 'leo', 'core', 'leo*.py') # pattern = g.os_path_finalize_join('leo','core','leo*.py') aList = [ g.shortFileName(fn) for fn in glob.glob(pattern) if g.shortFileName(fn) != '__init__.py' ] aList.extend([ 'runLeo.py', ]) return sorted(aList)
def find_c(self, path): """Return the commander associated with path, or None.""" g = self.g # type:ignore # mypy seems confused. g is a local var. self.update() path = g.os_path_normcase(path) short_path = g.shortFileName(path) for c in self.commanders_list: fn = g.os_path_normcase(c.fileName()) short_fn = g.shortFileName(fn) if fn == path or short_fn == short_path: return c return None
def callback(data=data): fn = data.fn self.put_log('%s: %s' % (kind, g.shortFileName(fn))) self.pid = subprocess.Popen( command, shell=shell, stderr=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True, ) if trace: self.put_log('===== Starting: %s for %s' % ( id(self.pid), g.shortFileName(fn)))
def getGuiPluginsList(): pattern = g.os_path_finalize_join('.', 'leo', 'plugins', 'qt_*.py') aList = [ g.shortFileName(fn) for fn in glob.glob(pattern) if g.shortFileName(fn) != '__init__.py' ] aList.extend([ 'free_layout', 'nested_splitter', ]) if 'qt_main.py' in aList: # Auto-generated file. aList.remove('qt_main.py') return sorted(aList)
def getGuiPluginsList(): pattern = g.os_path_finalize_join('.', 'leo', 'plugins', 'qt_*.py') aList = [ g.shortFileName(fn) for fn in glob.glob(pattern) if g.shortFileName(fn) != '__init__.py'] aList.extend([ 'free_layout', 'nested_splitter', ]) if 'qt_main.py' in aList: # Auto-generated file. aList.remove('qt_main.py') return sorted(aList)
def __init__(self, c, images): """Create a Recent Sections listbox dialog.""" self.c = c self.images = images self.label = None self.title = "Recent nodes for %s" % g.shortFileName(c.mFileName) self.lt_nav_button = self.rt_nav_button = None # Created by createFrame. # Create the show-recent-sections-dialog command. self.addCommand() # Add 'Recent' button to icon bar. self.addIconBarButtons() # Init the base class. (calls createFrame) # N.B. The base class contains positionList ivar. tkinterListBoxDialog.__init__(self, c, self.title, self.label) self.fillbox() # Must be done initially. if not recentInitiallyVisible: self.top.withdraw() self.updateButtons() self.addGeneratorCommands() c.bind(self.top, "<Up>", self.up) c.bind(self.top, "<Down>", self.down)
def __repr__(self): return 'PyTarget: %s kind: %s @others: %s p: %s' % ( self.state, self.kind, int(self.at_others_flag), g.shortFileName(self.p.h), )
def createOutlineFromCacheList(self, parent_v, aList, fileName, top=True): ''' Create outline structure from recursive aList built by makeCacheList. ''' trace = False and not g.unitTesting # and fileName.endswith('leoFileCommands.py') c = self.c if not c: g.internalError('no c') return if top: if trace: g.trace(g.shortFileName(fileName)) c.cacheListFileName = fileName if not aList: if trace: g.trace('no list') return h, b, gnx, children = aList if h is not None: v = parent_v # Does this destroy the ability to handle the rare case? v._headString = g.toUnicode(h) v._bodyString = g.toUnicode(b) for child_tuple in children: h, b, gnx, grandChildren = child_tuple if trace: g.trace('%30s %3s %s' % (gnx, len(grandChildren), h.strip())) isClone, child_v = self.fastAddLastChild(fileName, gnx, parent_v) if isClone: self.checkForChangedNodes(child_tuple, fileName, parent_v) else: self.createOutlineFromCacheList(child_v, child_tuple, fileName, top=False)
def __init__ (self,c,images): """Create a Recent Sections listbox dialog.""" self.c = c self.images = images self.label = None self.title = "Recent nodes for %s" % g.shortFileName(c.mFileName) self.lt_nav_button = self.rt_nav_button = None # Created by createFrame. # Create the show-recent-sections-dialog command. self.addCommand() # Add 'Recent' button to icon bar. self.addIconBarButtons() # Init the base class. (calls createFrame) # N.B. The base class contains positionList ivar. tkinterListBoxDialog.__init__(self,c,self.title,self.label) self.fillbox() # Must be done initially. if not recentInitiallyVisible: self.top.withdraw() self.updateButtons() self.addGeneratorCommands() c.bind(self.top,"<Up>",self.up) c.bind(self.top,"<Down>",self.down)
def __init__(self, filename, parent, **kwargs): ''' Called automatically from pyzo's createEditor function. ''' assert g.pyzo, g.callers() g.pr('\nOutlineEditorShim.__init__', g.shortFileName(filename)) # g.printObj(g.callers(30).split(','), tag='OutlineEditorShim.__init__') super().__init__(parent, **kwargs) # CodeEditorBase only passes args to *its* base class. self.setObjectName('OutlineEditorShim') self.c = None # Set in createOutlineFrame. self._filename = self.filename = filename # Essential, so the tab will close properly. self._name = self.name = os.path.split(filename)[1] # To set the tab's name properly. if not isinstance(self, CodeEditorBase): g.pr('\nOutlineEditorShim: using shims\n') # # Needed if this is just a QWidget. self._breakPoints = {} # self.breakPointsChanged.emit(self) # self.__breakPointArea.update() self.lineEndingsHumanReadable = 'CRLF' self.document = DocumentShim self.horizontalScrollBar = ScrollBarShim self.parser = g.TracingNullObject(tag='OutlineEditorShim.parser') self.textCursor = TextCursorShim self.verticalScrollBar = ScrollBarShim # Create the outline! self.createOutlineFrame()
def check_all(self, log_flag, paths, pyflakes_errors_only): '''Run pyflakes on all files in paths.''' from pyflakes import api, reporter total_errors = 0 for fn in sorted(paths): # Report the file name. sfn = g.shortFileName(fn) s = g.readFileIntoEncodedString(fn) if s.strip(): if not pyflakes_errors_only: g.es('Pyflakes: %s' % sfn) # Send all output to the log pane. class LogStream: def write(self, s): if s.strip(): g.es_print(s) # It *is* useful to send pyflakes errors to the console. r = reporter.Reporter( errorStream=LogStream(), warningStream=LogStream(), ) errors = api.check(s, sfn, r) total_errors += errors return total_errors
def check_all(self, log_flag, pyflakes_errors_only, roots): """Run pyflakes on all files in paths.""" try: from pyflakes import api, reporter except Exception: # ModuleNotFoundError return True # Pretend all is fine. total_errors = 0 for i, root in enumerate(roots): fn = self.finalize(root) sfn = g.shortFileName(fn) # #1306: nopyflakes if any([ z.strip().startswith('@nopyflakes') for z in g.splitLines(root.b) ]): continue # Report the file name. s = g.readFileIntoEncodedString(fn) if s and s.strip(): if not pyflakes_errors_only: g.es(f"Pyflakes: {sfn}") # Send all output to the log pane. r = reporter.Reporter( errorStream=self.LogStream(i, roots), warningStream=self.LogStream(i, roots), ) errors = api.check(s, sfn, r) total_errors += errors return total_errors
def regularize_whitespace(self, lines): """ Regularize leading whitespace in s: Convert tabs to blanks or vice versa depending on the @tabwidth in effect. """ kind = 'tabs' if self.tab_width > 0 else 'blanks' kind2 = 'blanks' if self.tab_width > 0 else 'tabs' fn = g.shortFileName(self.root.h) count, result, tab_width = 0, [], self.tab_width self.ws_error = False # 2016/11/23 if tab_width < 0: # Convert tabs to blanks. for n, line in enumerate(lines): i, w = g.skip_leading_ws_with_indent(line, 0, tab_width) # Use negative width. s = g.computeLeadingWhitespace(w, -abs(tab_width)) + line[i:] if s != line: count += 1 result.append(s) elif tab_width > 0: # Convert blanks to tabs. for n, line in enumerate(lines): # Use positive width. s = g.optimizeLeadingWhitespace(line, abs(tab_width)) if s != line: count += 1 result.append(s) if count: self.ws_error = True # A flag to check. if not g.unitTesting: # g.es_print('Warning: Intermixed tabs and blanks in', fn) # g.es_print('Perfect import test will ignoring leading whitespace.') g.es('changed leading %s to %s in %s line%s in %s' % ( kind2, kind, count, g.plural(count), fn)) if g.unitTesting: # Sets flag for unit tests. self.report('changed %s lines' % count) return result
def __repr__(self): return 'Target: %s @others: %s refs: %s p: %s' % ( self.state, int(self.at_others_flag), int(self.gen_refs), g.shortFileName(self.p.h), )
def add_class_names(self, p): """ Add class names to headlines for all descendant nodes. Called only when @bool add-context-to-headlines is True. """ if g.unitTesting: return # Don't changes the expected headlines. after, fn, class_name = None, None, None for p in p.self_and_subtree(): # Part 1: update the status. m = self.file_pattern.match(p.h) if m: prefix = m.group(1) fn = g.shortFileName(p.h[len(prefix) :].strip()) after, class_name = None, None continue if p.h.startswith('@path '): after, fn, class_name = None, None, None elif p.h.startswith('class '): class_name = p.h[5:].strip() if class_name: after = p.nodeAfterTree() continue elif p == after: after, class_name = None, None # Part 2: update the headline. if class_name: if not p.h.startswith(class_name): p.h = '%s.%s' % (class_name, p.h) elif fn and self.add_file_context: tag = ' (%s)' % fn if not p.h.endswith(tag): p.h += tag
def check_blanks_and_tabs(self, lines): """Check for intermixed blank & tabs.""" # Do a quick check for mixed leading tabs/blanks. fn = g.shortFileName(self.root.h) w = self.tab_width blanks = tabs = 0 for s in lines: lws = self.get_str_lws(s) blanks += lws.count(' ') tabs += lws.count('\t') # Make sure whitespace matches @tabwidth directive. if w < 0: ok = tabs == 0 message = 'tabs found with @tabwidth %s in %s' % (w, fn) elif w > 0: ok = blanks == 0 message = 'blanks found with @tabwidth %s in %s' % (w, fn) if ok: ok = (blanks == 0 or tabs == 0) message = 'intermixed blanks and tabs in: %s' % (fn) if not ok: if g.unitTesting: self.report(message) else: g.es(message) return ok
def fstringify_diff_files(event): """ Show the diffs that would result from fstringifying the external files at c.p. """ c = event.get('c') if not c or not c.p: return t1 = time.process_time() tag = 'fstringify-files-diff' g.es(f"{tag}...") roots = g.findRootsWithPredicate(c, c.p) for root in roots: filename = g.fullPath(c, root) if os.path.exists(filename): print('') print(g.shortFileName(filename)) changed = leoAst.Fstringify().fstringify_file_diff(filename) changed_s = 'changed' if changed else 'unchanged' g.es_print(f"{changed_s:>9}: {g.shortFileName(filename)}") else: print('') print(f"File not found:{filename}") g.es(f"File not found:\n{filename}") t2 = time.process_time() print('') g.es_print( f"{len(roots)} file{g.plural(len(roots))} in {t2 - t1:5.2f} sec.")
def fstringify_files(event): """fstringify one or more files at c.p.""" c = event.get('c') if not c or not c.p: return t1 = time.process_time() tag = 'fstringify-files' g.es(f"{tag}...") roots = g.findRootsWithPredicate(c, c.p) n_changed = 0 for root in roots: filename = g.fullPath(c, root) if os.path.exists(filename): print('') print(g.shortFileName(filename)) changed = leoAst.Fstringify().fstringify_file(filename) changed_s = 'changed' if changed else 'unchanged' if changed: n_changed += 1 g.es_print(f"{changed_s:>9}: {g.shortFileName(filename)}") else: print('') print(f"File not found:{filename}") g.es(f"File not found:\n{filename}") t2 = time.process_time() print('') g.es_print(f"total files: {len(roots)}, " f"changed files: {n_changed}, " f"in {t2 - t1:5.2f} sec.")
def open_dict_file(self, fn): '''Open or create the dict with the given fn.''' trace = False and not g.unitTesting language = self.language if not fn or not language: return None if g.app.spellDict: if trace: g.trace('already open', self.c.fileName(), fn) return g.app.spellDict if not g.os_path_exists(fn): # Fix bug 1175013: leo/plugins/spellpyx.txt is # both source controlled and customized. self.create(fn) if g.os_path_exists(fn): # Merge the local and global dictionaries. try: self.clean_dict(fn) d = enchant.DictWithPWL(language, fn) if trace: g.trace('open', g.shortFileName(self.c.fileName()), fn) except Exception: # This is off-putting, and not necessary. # g.es('Error reading dictionary file', fn) # g.es_exception() d = enchant.Dict(language) else: # A fallback. Unlikely to happen. d = enchant.Dict(language) return d
def start_process(self, c, command, kind, fn=None, link_pattern=None, link_root=None, shell=False, ): '''Start or queue a process described by command and fn.''' self.data = data = self.ProcessData(c, kind, fn, link_pattern, link_root, shell) if self.pid: # A process is already active. Add a new callback. def callback(data=data, kind=kind): fn = data.fn self.put_log('%s: %s\n' % (kind, g.shortFileName(fn))) self.pid = subprocess.Popen( command, shell=shell, stderr=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True, ) data.callback = callback self.process_queue.append(data) else: # Start the process immediately. self.kind = kind self.put_log('%s: %s\n' % (kind, g.shortFileName(fn))) self.pid = subprocess.Popen( command, shell=shell, stderr=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True, )
def getPluginsList(): '''Return a list of all important plugins.''' aList = [] # g.app.loadDir does not exist: use '.' instead. for theDir in ('', 'importers', 'writers'): pattern = g.os_path_finalize_join('.', 'leo', 'plugins', theDir, '*.py') for fn in glob.glob(pattern): sfn = g.shortFileName(fn) if sfn != '__init__.py': sfn = os.sep.join([theDir, sfn]) if theDir else sfn aList.append(sfn) remove = [ 'free_layout.py', # Gui-related. 'gtkDialogs.py', # Many errors, not important. 'leofts.py', # Not (yet) in leoPlugins.leo. 'nested_splitter.py', # Gui-related. 'qtGui.py', # Dummy file 'qt_main.py', # Created automatically. ] aList = sorted([z for z in aList if z not in remove]) # Remove all gui related items. for z in sorted(aList): if z.startswith('qt_'): aList.remove(z) # g.trace('\n'.join(aList)) return aList
def open_dict(self, fn, language): '''Open or create the dict with the given fn.''' trace = False and not g.unitTesting if not fn or not language: return d = g.app.spellDict if d: self.d = d if trace: g.trace('already open', self.c.fileName(), fn) return if not g.os_path_exists(fn): # Fix bug 1175013: leo/plugins/spellpyx.txt is both source controlled and customized. self.create(fn) if g.os_path_exists(fn): # Merge the local and global dictionaries. try: self.clean_dict(fn) self.d = enchant.DictWithPWL(language, fn) if trace: g.trace('open', g.shortFileName(self.c.fileName()), fn) except Exception: g.es_exception() g.error('not a valid dictionary file', fn) self.d = enchant.Dict(language) else: # A fallback. Unlikely to happen. self.d = enchant.Dict(language) # Use only a single copy of the dict. g.app.spellDict = self.d
def __init__ (self,c,images): """Create a Marks listbox dialog.""" self.c = c self.images = images self.label = None self.title = 'Marks for %s' % g.shortFileName(c.mFileName) # c.frame.title # Init the base class and call self.createFrame. tkinterListBoxDialog.__init__(self,c,self.title,self.label) # Create the show-marks-dialog command. self.addCommand() if not marksInitiallyVisible: self.top.withdraw() self.addButtons() # Create the marks menu generator commands. self.addGeneratorCommands() c.bind(self.top,"<Up>",self.up) c.bind(self.top,"<Down>",self.down)
def getPluginsList(): '''Return a list of all important plugins.''' aList = [] # g.app.loadDir does not exist: use '.' instead. for theDir in ('','importers','writers'): pattern = g.os_path_finalize_join('.','leo','plugins',theDir,'*.py') for fn in glob.glob(pattern): sfn = g.shortFileName(fn) if sfn != '__init__.py': sfn = os.sep.join([theDir,sfn]) if theDir else sfn aList.append(sfn) remove = [ 'free_layout.py', # Gui-related. 'gtkDialogs.py', # Many errors, not important. 'leofts.py', # Not (yet) in leoPlugins.leo. 'nested_splitter.py', # Gui-related. 'qtGui.py', # Dummy file 'qt_main.py', # Created automatically. ] aList = sorted([z for z in aList if z not in remove]) # Remove all gui related items. for z in sorted(aList): if z.startswith('qt_'): aList.remove(z) # g.trace('\n'.join(aList)) return aList
def readFile(self, fileName, root): ''' Read the file from the cache if possible. Return (s,ok,key) ''' trace = (False or g.app.debug) and not g.unitTesting showHits, showLines, verbose = False, False, True sfn = g.shortFileName(fileName) if not g.enableDB: if trace and verbose: g.trace('g.enableDB is False', sfn) return '', False, None s = g.readFileIntoEncodedString(fileName, silent=True) if s is None: if trace: g.trace('empty file contents', sfn) return s, False, None assert not g.isUnicode(s) if trace and showLines: for i, line in enumerate(g.splitLines(s)): print('%3d %s' % (i, repr(line))) # There will be a bug if s is not already an encoded string. key = self.fileKey(root.h, s, requireEncodedString=True) ok = self.db and key in self.db if ok: if trace and showHits: g.trace('cache hit', key[-6:], sfn) # Delete the previous tree, regardless of the @<file> type. while root.hasChildren(): root.firstChild().doDelete() # Recreate the file from the cache. aList = self.db.get(key) self.createOutlineFromCacheList(root.v, aList, fileName=fileName) elif trace: g.trace('cache miss', key[-6:], sfn) return s, ok, key
def getPluginsList(): """Return a list of all important plugins.""" aList = [] # g.app.loadDir does not exist: use '.' instead. for theDir in ("", "importers", "writers"): pattern = g.os_path_finalize_join(".", "leo", "plugins", theDir, "*.py") for fn in glob.glob(pattern): sfn = g.shortFileName(fn) if sfn != "__init__.py": sfn = os.sep.join([theDir, sfn]) if theDir else sfn aList.append(sfn) remove = [ "free_layout.py", # Gui-related. "gtkDialogs.py", # Many errors, not important. "leofts.py", # Not (yet) in leoPlugins.leo. "nested_splitter.py", # Gui-related. "qtGui.py", # Dummy file "qt_main.py", # Created automatically. ] aList = sorted([z for z in aList if z not in remove]) # Remove all gui related items. for z in sorted(aList): if z.startswith("qt_"): aList.remove(z) # g.trace('\n'.join(aList)) return aList
def check_all(self, log_flag, paths): '''Run pyflakes on all files in paths.''' from pyflakes import api, reporter total_errors = 0 for fn in sorted(paths): # Report the file name. sfn = g.shortFileName(fn) s = g.readFileIntoEncodedString(fn, silent=False) if s.strip(): g.es('Pyflakes: %s' % sfn) # Send all output to the log pane. class LogStream: def write(self, s): if s.strip(): g.es_print(s) # It *is* useful to send pyflakes errors to the console. r = reporter.Reporter( errorStream=LogStream(), warningStream=LogStream(), ) errors = api.check(s, sfn, r) total_errors += errors return total_errors
def createOutlineFromCacheList(self, parent_v, aList, fileName, top=True): """ Create outline structure from recursive aList built by makeCacheList. """ trace = False and not g.unitTesting c = self.c if not c: g.internalError('no c') if top: if trace: g.trace(g.shortFileName(fileName)) c.cacheListFileName = fileName if not aList: if trace: g.trace('no list') return h, b, gnx, children = aList if h is not None: v = parent_v v._headString = g.toUnicode(h) # 2017/01/16 v._bodyString = g.toUnicode(b) # 2017/01/16 for z in children: h, b, gnx, grandChildren = z isClone, child_v = self.fastAddLastChild(parent_v, gnx) if isClone: self.reportChangedClone(child_v, b, h, gnx) else: self.createOutlineFromCacheList( child_v, z, fileName, top=False)
def getPluginsList(): '''Return a list of all important plugins.''' aList = [] # g.app.loadDir does not exist: use '.' instead. for theDir in ('importers','writers'): pattern = g.os_path_finalize_join('.','leo','plugins',theDir,'*.py') for fn in glob.glob(pattern): sfn = g.shortFileName(fn) if sfn != '__init__.py': aList.append(os.sep.join([theDir,sfn])) aList.extend([ 'baseNativeTree', 'bookmarks', 'contextmenu', 'leoOPML', 'lineNumbers', # 'mod_http', 'mod_scripting', 'nav_qt', 'quicksearch', 'todo', 'vim.py', 'viewrendered.py', 'xemacs.py', ]) return aList
def add_class_names(self, p): '''Add class names to headlines for all descendant nodes.''' if g.app.unitTesting: return # Don't changes the expected headlines. after, fn, class_name = None, None, None for p in p.self_and_subtree(): # Part 1: update the status. m = self.file_pattern.match(p.h) if m: prefix = m.group(1) fn = g.shortFileName(p.h[len(prefix):].strip()) after, class_name = None, None continue elif p.h.startswith('@path '): after, fn, class_name = None, None, None elif p.h.startswith('class '): class_name = p.h[5:].strip() if class_name: after = p.nodeAfterTree() continue elif p == after: after, class_name = None, None # Part 2: update the headline. if class_name: if not p.h.startswith(class_name): p.h = '%s.%s' % (class_name, p.h) elif fn: tag = ' (%s)' % fn if not p.h.endswith(tag): p.h += tag
def shadowPathName (self,filename): '''Return the full path name of filename, resolved using c.fileName()''' x = self ; c = x.c baseDir = x.baseDirName() fileDir = g.os_path_dirname(filename) # 2011/01/26: bogomil: redirect shadow dir if self.shadow_in_home_dir: # Each .leo file has a separate shadow_cache in base dir fname = "_".join([os.path.splitext(os.path.basename(c.mFileName))[0],"shadow_cache"]) # On Windows incorporate the drive letter to the private file path if os.name == "nt": fileDir = fileDir.replace(':','%') # build the chache path as a subdir of the base dir fileDir = "/".join([baseDir, fname, fileDir]) return baseDir and c.os_path_finalize_join( baseDir, fileDir, # Bug fix: honor any directories specified in filename. x.shadow_subdir, x.shadow_prefix + g.shortFileName(filename))
def check_blanks_and_tabs(self, lines): '''Check for intermixed blank & tabs.''' # Do a quick check for mixed leading tabs/blanks. fn = g.shortFileName(self.root.h) w = self.tab_width blanks = tabs = 0 for s in g.splitLines(lines): lws = self.get_str_lws(s) blanks += lws.count(' ') tabs += lws.count('\t') # Make sure whitespace matches @tabwidth directive. if w < 0: ok = tabs == 0 message = 'tabs found with @tabwidth %s in %s' % (w, fn) elif w > 0: ok = blanks == 0 message = 'blanks found with @tabwidth %s in %s' % (w, fn) if ok: ok = blanks == 0 or tabs == 0 message = 'intermixed blanks and tabs in: %s' % (fn) if not ok: if g.unitTesting: self.report(message) else: g.es(message) return ok
def open_dict_file(self, fn): '''Open or create the dict with the given fn.''' trace = False and not g.unitTesting language = self.language if not fn or not language: return None if g.app.spellDict: if trace: g.trace('already open', self.c.fileName(), fn) return g.app.spellDict if not g.os_path_exists(fn): # Fix bug 1175013: leo/plugins/spellpyx.txt is # both source controlled and customized. self.create(fn) if g.os_path_exists(fn): # Merge the local and global dictionaries. try: self.clean_dict(fn) d = enchant.DictWithPWL(language, fn) if trace: g.trace('open', g.shortFileName(self.c.fileName()), fn) except Exception: g.es('Error reading dictionary file', fn) g.es_exception() d = enchant.Dict(language) else: # A fallback. Unlikely to happen. d = enchant.Dict(language) return d
def callback(data=data, kind=kind): fn = data.fn self.put_log('%s: %s\n' % (kind, g.shortFileName(fn))) self.pid = subprocess.Popen( command, shell=shell, stderr=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True, )
def destroy_external_file(self, ef): '''Destroy the file corresponding to the given ExternalFile instance.''' trace = False and not g.unitTesting # Do not use g.trace here. if ef.path and g.os_path_exists(ef.path): try: os.remove(ef.path) if trace: print("deleting temp file: %s" % g.shortFileName(ef.path)) except Exception: if trace: print("can not delete temp file: %s" % ef.path)
def has_changed(self, c, path): '''Return True if p's external file has changed outside of Leo.''' trace = False and not g.unitTesting verbose_init = False tag = 'efc.has_changed' if not g.os_path_exists(path): if trace: print('%s:does not exist %s' % (tag, path)) return False if g.os_path_isdir(path): if trace: print('%s: %s is a directory' % (tag, path)) return False fn = g.shortFileName(path) # First, check the modification times. old_time = self.get_time(path) new_time = self.get_mtime(path) if not old_time: # Initialize. self.set_time(path, new_time) self.checksum_d[path] = checksum = self.checksum(path) if trace and verbose_init: print('%s:init %s %s %s' % (tag, checksum, c.shortFileName(), path)) elif trace: # Only print one message per commander. d = self.has_changed_d val = d.get(c) if not val: d[c] = True print('%s:init %s' % (tag, c.shortFileName())) return False if old_time == new_time: # print('%s:times match %s %s' % (tag,c.shortFileName(),path)) return False # Check the checksums *only* if the mod times don't match. old_sum = self.checksum_d.get(path) new_sum = self.checksum(path) if new_sum == old_sum: # The modtime changed, but it's contents didn't. # Update the time, so we don't keep checking the checksums. # Return False so we don't prompt the user for an update. if trace: print('%s:unchanged %s %s' % (tag, old_time, new_time)) self.set_time(path, new_time) return False else: # The file has really changed. if trace: print('%s:changed %s %s %s' % (tag, old_sum, new_sum, fn)) assert old_time, path if 0: # Fix bug 208: external change overwrite protection only works once # https://github.com/leo-editor/leo-editor/issues/208 # These next two lines mean that if the Leo version # is changed (dirtied) again, overwrite will occur without warning. self.set_time(path, new_time) self.checksum_d[path] = new_sum return True