def scanForMultiPath (c): '''Return a dictionary whose keys are fileNames and whose values are lists of paths to which the fileName is to be written. New in version 0.6 of this plugin: use ';' to separate paths in @multipath statements.''' global multiprefix, multipath d, sep = {}, ';' for fileName in files: # Keys are fileNames, values are root positions. root = files[fileName] default_directory = g.os_path_dirname(fileName) fileName = g.os_path_join(default_directory, fileName) positions = [p.copy() for p in root.self_and_parents()] positions.reverse() prefix = '' for p in positions: lines = p.b.split('\n') # Calculate the prefix fisrt. for s in lines: if s.startswith(multiprefix): prefix = s[len(multiprefix):].strip() # Handle the paths after the prefix is in place. for s in lines: if s.startswith(multipath): s = s[len(multipath):].strip() paths = s.split(sep) paths = [z.strip() for z in paths] if prefix: paths = [g.os_path_join(default_directory,prefix,z) for z in paths] else: paths = [g.os_path_join(default_directory,z) for z in paths] aList = d.get(fileName,[]) aList.extend(paths) d[fileName] = aList return d
def _path_from_pos(c, p): """_path_from_pos - get folder for position FIXME: should be in Leo core somewhere. Args: p (position): position Returns: str: path """ p = p.copy() def atfile(p): word0 = p.h.split()[0] return ( word0 in g.app.atFileNames|set(['@auto']) or word0.startswith('@auto-') ) aList = g.get_directives_dict_list(p) path = c.scanAtPathDirectives(aList) while c.positionExists(p): if atfile(p): # see if it's a @<file> node of some sort nodepath = p.h.split(None, 1)[-1] nodepath = g.os_path_join(path, nodepath) if not g.os_path_isdir(nodepath): # remove filename nodepath = g.os_path_dirname(nodepath) if g.os_path_isdir(nodepath): # append if it's a directory path = nodepath break p.moveToParent() return path
def dirName (self,filename): '''Return the directory for filename.''' x = self return g.os_path_dirname(x.pathName(filename))
def xdb_command(event): '''Start the external debugger on a toy test program.''' c = event.get('c') if not c: return path = g.fullPath(c, c.p) if not path: g.trace('Not in an @<file> tree') return if not g.os_path_exists(path): return g.trace('not found', path) os.chdir(g.os_path_dirname(path)) xdb = getattr(g.app, 'xdb', None) if xdb: # Just issue a message. xdb.write('xdb active: use Quit button or db-q to terminate') # Killing the previous debugger works, # *provided* we don't try to restart xdb! # That would create a race condition on g.app.xdb. # xdb.do_quit() else: # Start the debugger in a separate thread. g.app.xdb = xdb = Xdb(path) xdb.start() xdb.qr.put(['clear-stdout'])
def shadowDirName (self,filename): '''Return the directory for the shadow file corresponding to filename.''' x = self return g.os_path_dirname(x.shadowPathName(filename))
def onIconDoubleClick(tag, keywords): """ Read or write a bibtex file when the node is double-clicked. Write the @bibtex tree as bibtex file when the root node is double-clicked. If it has no child nodes, read bibtex file. """ p = keywords.get("p") or keywords.get("v") c = keywords.get("c") if not c or not p: return h = p.h.strip() if g.match_word(h, 0, "@bibtex"): fn = g.os_path_finalize_join(g.os_path_dirname(c.fileName() or ""), h[8:]) if p.hasChildren(): bibFile = open(fn, "w") writeTreeAsBibTex(bibFile, p, c) bibFile.close() g.es("wrote: %s" % fn) else: try: bibFile = open(fn, "r") except IOError: g.es("not found: %s" % fn, color="red") return g.es("reading: " + fn) readBibTexFileIntoTree(bibFile, c) bibFile.close()
def cmd_PickDir(c): """cmd_PickDir - Show user a folder picker to create a new top level @path node :Parameters: - `c`: outline """ p = c.p aList = g.get_directives_dict_list(p) path = c.scanAtPathDirectives(aList) if p.h.startswith('@'): # see if it's a @<file> node of some sort nodepath = p.h.split(None, 1)[-1] nodepath = g.os_path_join(path, nodepath) if not g.os_path_isdir(nodepath): # remove filename nodepath = g.os_path_dirname(nodepath) if g.os_path_isdir(nodepath): # append if it's a directory path = nodepath ocwd = os.getcwd() try: os.chdir(path) except OSError: g.es("Couldn't find path %s"%path) dir_ = g.app.gui.runOpenDirectoryDialog("Pick a folder", "Pick a folder") os.chdir(ocwd) if not dir_: g.es("No folder selected") return nd = c.p.insertAfter() nd.h = "@path %s" % dir_ c.redraw()
def baseDirName(self): x = self; c = x.c; filename = c.fileName() if filename: return g.os_path_dirname(c.os_path_finalize(filename)) else: self.error('Can not compute shadow path: .leo file has not been saved') return None
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 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 saveAs(self, event=None, fileName=None): '''Save a Leo outline to a file with a new filename.''' c = self; p = c.p # Do this now: w may go away. w = g.app.gui.get_focus(c) inBody = g.app.gui.widget_name(w).startswith('body') if inBody: p.saveCursorAndScroll() if g.app.disableSave: g.es("save commands disabled", color="purple") return c.init_error_dialogs() # 2013/09/28: add fileName keyword arg for leoBridge scripts. if fileName: c.frame.title = g.computeWindowTitle(fileName) c.mFileName = fileName # Make sure we never pass None to the ctor. if not c.mFileName: c.frame.title = "" if not fileName: fileName = ''.join(c.k.givenArgs) if not fileName: fileName = g.app.gui.runSaveFileDialog(c, initialfile=c.mFileName, title="Save As", filetypes=[g.fileFilters('LEOFILES')], defaultextension=g.defaultLeoFileExtension(c)) c.bringToFront() if fileName: # Fix bug 998090: save file as doesn't remove entry from open file list. if c.mFileName: g.app.forgetOpenFile(c.mFileName) # Don't change mFileName until the dialog has suceeded. c.mFileName = g.ensure_extension(fileName, g.defaultLeoFileExtension(c)) # Part of the fix for https://bugs.launchpad.net/leo-editor/+bug/1194209 c.frame.title = title = c.computeWindowTitle(c.mFileName) c.frame.setTitle(title) # 2013/08/04: use c.computeWindowTitle. c.openDirectory = c.frame.openDirectory = g.os_path_dirname(c.mFileName) # Bug fix in 4.4b2. # Calls c.setChanged(False) if no error. if g.app.qt_use_tabs and hasattr(c.frame, 'top'): c.frame.top.leo_master.setTabName(c, c.mFileName) c.fileCommands.saveAs(c.mFileName) g.app.recentFilesManager.updateRecentFiles(c.mFileName) g.chdir(c.mFileName) # Done in FileCommands.saveAs. # c.redraw_after_icons_changed() c.raise_error_dialogs(kind='write') # *Safely* restore focus, without using the old w directly. if inBody: c.bodyWantsFocus() p.restoreCursorAndScroll() else: c.treeWantsFocus()
def create(self, fn): '''Create the given file with empty contents.''' theDir = g.os_path_dirname(fn) g.makeAllNonExistentDirectories(theDir, c=self.c, force=True, verbose=True) # Make the directories as needed. try: f = open(fn, mode='wb') f.close() g.note('created: %s' % (fn)) except IOError: g.error('can not create: %s' % (fn)) except Exception: g.error('unexpected error creating: %s' % (fn)) g.es_exception()
def _getpath (self,p): c = self.c dict = c.scanAllDirectives(p) d = dict.get("path") if p.isAnyAtFileNode(): filename = p.anyAtFileNodeName() filename = g.os_path_join(d,filename) if filename: d = g.os_path_dirname(filename) if d is None: return "" else: return g.os_path_normpath(d)
def run(fn, verbose): '''Run pylint on fn.''' # theDir is empty for the -f option. from pylint import lint assert lint # Note: g.app does not exist. base_dir = os.path.dirname(__file__) home_dir = os.path.expanduser('~') if hasattr(os.path, 'expanduser') else '' rc_fn = 'pylint-leo-rc.txt' table = ( os.path.abspath(os.path.join(home_dir, '.leo', rc_fn)), os.path.abspath(os.path.join(base_dir, 'leo', 'test', rc_fn)), ) for rc_fn in table: if os.path.exists(rc_fn): break else: print('pylint-leo.py: %s not found in leo/test or ~/.leo.' % (rc_fn)) return if not os.path.exists(fn): print('pylint-leo.py: file not found: %s' % (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. if 1: # Invoke pylint directly. # Escaping args is harder here because we are creating an args array. is_win = sys.platform.startswith('win') args = ','.join(["'--rcfile=%s'" % (rc_fn), "'%s'" % (fn)]) if is_win: args = args.replace('\\','\\\\') command = '%s -c "from pylint import lint; args=[%s]; lint.Run(args)"' % ( sys.executable, args) if not is_win: command = shlex.split(command) else: # Use g.run_pylint. args = ','.join(["fn=r'%s'" % (fn), "rc=r'%s'" % (rc_fn)]) command = '%s -c "import leo.core.leoGlobals as g; g.run_pylint(%s)"' % ( sys.executable, args) # g.trace('===== pylint-leo.run: %s' % command) # If shell is True, it is recommended to pass args as a string rather than as a sequence. proc = subprocess.Popen(command, shell=False) proc.communicate()
def replaceFileWithString (self,fn,s): '''Replace the file with s if s is different from theFile's contents. Return True if theFile was changed. ''' trace = False and not g.unitTesting ; verbose = False x = self exists = g.os_path_exists(fn) if exists: # Read the file. Return if it is the same. s2,e = g.readFileIntoString(fn) if s2 is None: return False if s == s2: if not g.unitTesting: g.es('unchanged:',fn) return False # Issue warning if directory does not exist. theDir = g.os_path_dirname(fn) if theDir and not g.os_path_exists(theDir): if not g.unitTesting: x.error('not written: %s directory not found' % fn) return False # Replace the file. try: f = open(fn,'wb') # 2011/09/09: Use self.encoding. f.write(g.toEncodedString(s,encoding=self.encoding)) if trace: g.trace('encoding',self.encoding) if verbose: g.trace('fn',fn, '\nlines...\n%s' %(g.listToString(g.splitLines(s))), '\ncallers',g.callers(4)) f.close() if not g.unitTesting: # g.trace('created:',fn,g.callers()) if exists: g.es('wrote:',fn) else: g.es('created:',fn) return True except IOError: x.error('unexpected exception writing file: %s' % (fn)) g.es_exception() return False
def findDebugger(self): '''Find the debugger using settings.''' c = self.c pythonDir = g.os_path_dirname(sys.executable) debuggers = ( c.config.getString('debugger-path'), g.os_path_join(pythonDir, 'Lib', 'site-packages', 'winpdb.py'), # winpdb 1.1.2 or newer g.os_path_join(pythonDir, 'scripts', '_winpdb.py'), # oder version. ) for debugger in debuggers: if debugger: debugger = c.os_path_finalize(debugger) if g.os_path_exists(debugger): return debugger g.warning('debugger does not exist:', debugger) g.es('no debugger found.') return None
def run(fn, verbose): """Run pylint on fn.""" # theDir is empty for the -f option. from pylint import lint assert lint # Note: g.app does not exist. base_dir = os.path.dirname(__file__) home_dir = os.path.expanduser('~') rc_fn = 'pylint-leo-rc.txt' table = ( os.path.abspath(os.path.join(home_dir, '.leo', rc_fn)), os.path.abspath(os.path.join(base_dir, 'leo', 'test', rc_fn)), ) for rc_fn in table: if os.path.exists(rc_fn): break else: print('pylint-leo.py: %s not found in leo/test or ~/.leo.' % (rc_fn)) return if not os.path.exists(fn): print('pylint-leo.py: file not found: %s' % (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. if 1: # Invoke pylint directly. # Escaping args is harder here because we are creating an args array. is_win = sys.platform.startswith('win') args = ','.join(["'--rcfile=%s'" % (rc_fn), "'%s'" % (fn)]) if is_win: args = args.replace('\\', '\\\\') command = '%s -c "from pylint import lint; args=[%s]; lint.Run(args)"' % ( sys.executable, args) if not is_win: command = shlex.split(command) else: # Use g.run_pylint. args = ','.join(["fn=r'%s'" % (fn), "rc=r'%s'" % (rc_fn)]) command = '%s -c "import leo.core.leoGlobals as g; g.run_pylint(%s)"' % ( sys.executable, args) # If shell is True, it is recommended to pass args as a string rather than as a sequence. proc = subprocess.Popen(command, shell=False) proc.communicate()
def run(fn, verbose): '''Run pylint on fn.''' # theDir is empty for the -f option. from pylint import lint assert lint # g.trace('(pylint-leo.py)', os.path.abspath(os.curdir)) # 2016/10/20: The old code only runs if os.curdir is the leo-editor folder. if 1: path = os.path.dirname(__file__) rc_fn = os.path.abspath( os.path.join(path, 'leo', 'test', 'pylint-leo-rc.txt')) else: rc_fn = os.path.abspath( os.path.join('leo', 'test', 'pylint-leo-rc.txt')) if not os.path.exists(rc_fn): print('pylint-leo.py: rc file not found: %s' % (rc_fn)) return if not os.path.exists(fn): print('pylint-leo.py: file not found: %s' % (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. if 1: # Invoke pylint directly. # Escaping args is harder here because we are creating an args array. is_win = sys.platform.startswith('win') args = ','.join(["'--rcfile=%s'" % (rc_fn), "'%s'" % (fn)]) if is_win: args = args.replace('\\', '\\\\') command = '%s -c "from pylint import lint; args=[%s]; lint.Run(args)"' % ( sys.executable, args) if not is_win: command = shlex.split(command) else: # Use g.run_pylint. args = ','.join(["fn=r'%s'" % (fn), "rc=r'%s'" % (rc_fn)]) command = '%s -c "import leo.core.leoGlobals as g; g.run_pylint(%s)"' % ( sys.executable, args) # g.trace('===== pylint-leo.run: %s' % command) # If shell is True, it is recommended to pass args as a string rather than as a sequence. proc = subprocess.Popen(command, shell=False) proc.communicate()
def replaceFileWithString(self, fn, s): '''Replace the file with s if s is different from theFile's contents. Return True if theFile was changed. ''' trace = False and not g.unitTesting verbose = False x = self exists = g.os_path_exists(fn) if exists: # Read the file. Return if it is the same. s2, e = g.readFileIntoString(fn) if s2 is None: return False if s == s2: if not g.unitTesting: g.es('unchanged:', fn) return False # Issue warning if directory does not exist. theDir = g.os_path_dirname(fn) if theDir and not g.os_path_exists(theDir): if not g.unitTesting: x.error('not written: %s directory not found' % fn) return False # Replace the file. try: f = open(fn, 'wb') # 2011/09/09: Use self.encoding. f.write(g.toEncodedString(s, encoding=self.encoding)) if trace: g.trace('encoding', self.encoding) if verbose: g.trace( 'fn', fn, '\nlines...\n%s' % (g.listToString(g.splitLines(s))), '\ncallers', g.callers(4)) f.close() if not g.unitTesting: # g.trace('created:',fn,g.callers()) if exists: g.es('wrote:', fn) else: g.es('created:', fn) return True except IOError: x.error('unexpected exception writing file: %s' % (fn)) g.es_exception() return False
def findDebugger(self): '''Find the debugger using settings.''' c = self.c pythonDir = g.os_path_dirname(sys.executable) debuggers = ( c.config.getString('debugger_path'), g.os_path_join(pythonDir, 'Lib', 'site-packages', 'winpdb.py'), # winpdb 1.1.2 or newer g.os_path_join(pythonDir, 'scripts', '_winpdb.py'), # oder version. ) for debugger in debuggers: if debugger: debugger = c.os_path_finalize(debugger) if g.os_path_exists(debugger): return debugger else: g.warning('debugger does not exist:', debugger) g.es('no debugger found.') return None
def doSubprocessTable(): if 1: pythonDir = g.os_path_dirname(sys.executable) idle = g.os_path_abspath( g.os_path_join(pythonDir, 'Lib', 'idlelib', 'idle.pyw')) table = ( ( "Idle", "Alt+Ctrl+I", ( "subprocess.Popen", # ["pythonw", "C:/Python24/Lib/idlelib/idle.pyw"], ".py")), ["pythonw", idle], ".py")), ("Word", "Alt+Ctrl+W", ("subprocess.Popen", "C:/Program Files/Microsoft Office/Office/WINWORD.exe", None)), ("WordPad", "Alt+Ctrl+T", ("subprocess.Popen", "C:/Program Files/Windows NT/Accessories/wordpad.exe", None)), ) else: # Jim Sizelove's table table = ( ("Emacs", "Alt+Ctrl+E", ("subprocess.Popen", "C:/Program Files/Emacs/bin/emacs.exe", None)), ("Gvim", "Alt+Ctrl+G", ("subprocess.Popen", [ "C:/Program Files/Vim/vim63/gvim.exe", "--servername", "LEO", "--remote-silent" ], None)), ("Idle", "Alt+Ctrl+I", ("subprocess.Popen", ["pythonw", "C:/Python24/Lib/idlelib/idle.pyw"], ".py")), ("NotePad", "Alt+Ctrl+N", ("os.startfile", None, ".txt")), ("PythonWin", "Alt+Ctrl+P", ("subprocess.Popen", "C:/Python24/Lib/site-packages/pythonwin/Pythonwin.exe", None)), ("WordPad", "Alt+Ctrl+W", ("subprocess.Popen", "C:/Program Files/Windows NT/Accessories/wordpad.exe", None)), ) return table
def run(fn, verbose): '''Run pylint on fn.''' # theDir is empty for the -f option. from pylint import lint assert lint # g.trace('(pylint-leo.py)', os.path.abspath(os.curdir)) # 2016/10/20: The old code only runs if os.curdir is the leo-editor folder. if 1: path = os.path.dirname(__file__) rc_fn = os.path.abspath(os.path.join(path,'leo','test','pylint-leo-rc.txt')) else: rc_fn = os.path.abspath(os.path.join('leo','test','pylint-leo-rc.txt')) if not os.path.exists(rc_fn): print('pylint-leo.py: rc file not found: %s' % (rc_fn)) return if not os.path.exists(fn): print('pylint-leo.py: file not found: %s' % (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. if 1: # Invoke pylint directly. # Escaping args is harder here because we are creating an args array. is_win = sys.platform.startswith('win') args = ','.join(["'--rcfile=%s'" % (rc_fn), "'%s'" % (fn)]) if is_win: args = args.replace('\\','\\\\') command = '%s -c "from pylint import lint; args=[%s]; lint.Run(args)"' % ( sys.executable, args) if not is_win: command = shlex.split(command) else: # Use g.run_pylint. args = ','.join(["fn=r'%s'" % (fn), "rc=r'%s'" % (rc_fn)]) command = '%s -c "import leo.core.leoGlobals as g; g.run_pylint(%s)"' % ( sys.executable, args) # g.trace('===== pylint-leo.run: %s' % command) # If shell is True, it is recommended to pass args as a string rather than as a sequence. proc = subprocess.Popen(command, shell=False) proc.communicate()
def doDefaultTable (): if 1: # Default table. pythonDir = g.os_path_dirname(sys.executable) idle = g.os_path_abspath(g.os_path_join(pythonDir,'tools','idle','idle.py')) idle_arg = "%s -e" % idle table = ( # Opening idle this way doesn't work so well. # ("&Idle", "Alt+Shift+I",("os.system",idle_arg,".py")), ("&Word", "Alt+Shift+W",("os.startfile",None,".doc")), ("Word&Pad","Alt+Shift+T",("os.startfile",None,".txt"))) elif 0: # Test table. table = ("&Word","Alt+Shift+W",("os.startfile",None,".doc")), elif 0: # David McNab's table. table = ("X&Emacs", "Ctrl+E", ("os.spawnl","/usr/bin/gnuclient", None)), return table
def onIconDoubleClick(tag, keywords): """ Read or write a bibtex file when the node is double-clicked. Write the @bibtex tree as bibtex file when the root node is double-clicked. If it has no child nodes, read bibtex file. """ p = keywords.get("p") or keywords.get("v") c = keywords.get("c") if not c or not p: return h = p.h.strip() if g.match_word(h, 0, "@bibtex"): base = g.os_path_dirname(c.fileName() or '') fn = g.os_path_finalize_join(base, h[8:]) if p.hasChildren(): writeTreeAsBibTex(c, fn, p) else: readBibTexFileIntoTree(c, fn, p)
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 g.os_path_finalize_join( # 1341 baseDir, fileDir, # Bug fix: honor any directories specified in filename. x.shadow_subdir, x.shadow_prefix + g.shortFileName(filename))
def create(self, fn): """Create the given file with empty contents.""" # Make the directories as needed. theDir = g.os_path_dirname(fn) if theDir: ok = g.makeAllNonExistentDirectories(theDir) # #1453: Don't assume the directory exists. if not ok: g.error(f"did not create directory: {theDir}") return # Create the file. try: f = open(fn, mode='wb') f.close() g.note(f"created: {fn}") except IOError: g.error(f"can not create: {fn}") except Exception: g.error(f"unexpected error creating: {fn}") g.es_exception()
def doDefaultTable(): if 1: # Default table. pythonDir = g.os_path_dirname(sys.executable) idle = g.os_path_abspath( g.os_path_join(pythonDir, 'tools', 'idle', 'idle.py')) idle_arg = "%s -e" % idle table = ( # Opening idle this way doesn't work so well. # ("&Idle", "Alt+Shift+I",("os.system",idle_arg,".py")), ("&Word", "Alt+Shift+W", ("os.startfile", None, ".doc")), ("Word&Pad", "Alt+Shift+T", ("os.startfile", None, ".txt"))) elif 0: # Test table. table = ("&Word", "Alt+Shift+W", ("os.startfile", None, ".doc")), elif 0: # David McNab's table. table = ("X&Emacs", "Ctrl+E", ("os.spawnl", "/usr/bin/gnuclient", None)), return table
def scanForMultiPath(c): """Return a dictionary whose keys are fileNames and whose values are lists of paths to which the fileName is to be written. New in version 0.6 of this plugin: use ';' to separate paths in @multipath statements.""" global multiprefix, multipath d: Dict = {} sep = ';' for fileName in files: # Keys are fileNames, values are root positions. root = files[fileName] default_directory = g.os_path_dirname(fileName) fileName = g.os_path_join(default_directory, fileName) positions = [p.copy() for p in root.self_and_parents()] positions.reverse() prefix = '' for p in positions: lines = p.b.split('\n') # Calculate the prefix fisrt. for s in lines: if s.startswith(multiprefix): prefix = s[len(multiprefix):].strip() # Handle the paths after the prefix is in place. for s in lines: if s.startswith(multipath): s = s[len(multipath):].strip() paths = s.split(sep) paths = [z.strip() for z in paths] if prefix: paths = [ g.os_path_join(default_directory, prefix, z) for z in paths ] else: paths = [ g.os_path_join(default_directory, z) for z in paths ] aList = d.get(fileName, []) aList.extend(paths) d[fileName] = aList return d
def replaceFileWithString(self, encoding, fileName, s): ''' Replace the file with s if s is different from theFile's contents. Return True if theFile was changed. ''' x, c = self, self.c exists = g.os_path_exists(fileName) if exists: # Read the file. Return if it is the same. s2, e = g.readFileIntoString(fileName) if s2 is None: return False if s == s2: report = c.config.getBool('report-unchanged-files', default=True) if report and not g.unitTesting: g.es('unchanged:', fileName) return False # Issue warning if directory does not exist. theDir = g.os_path_dirname(fileName) if theDir and not g.os_path_exists(theDir): if not g.unitTesting: x.error('not written: %s directory not found' % fileName) return False # Replace the file. try: with open(fileName, 'wb') as f: # Fix bug 1243847: unicode error when saving @shadow nodes. f.write(g.toEncodedString(s, encoding=encoding)) c.setFileTimeStamp(fileName) # Fix #1053. This is an *ancient* bug. if not g.unitTesting: kind = 'wrote' if exists else 'created' g.es('%-6s: %s' % (kind, fileName)) return True except IOError: x.error('unexpected exception writing file: %s' % (fileName)) g.es_exception() return False
def select_node(self, tag, kwargs): c = kwargs['c'] if c != self.c: return p = kwargs['new_p'] self.v = p.v # to ensure unselect_node is working on the right node # currently (20130814) insert doesn't trigger unselect/select, but # even if it did, this would be safest data = self.template if p.b.startswith('<'): # already rich text, probably content = p.b self.was_rich = True else: self.was_rich = p.b.strip() == '' # put anything except whitespace in a <pre/> content = "<pre>%s</pre>" % p.b if not self.was_rich else '' data = data.replace('[CONTENT]', content) # replace textarea with CKEditor, with or without config. if self.config: data = data.replace('[CONFIG]', ', ' + self.config) else: data = data.replace('[CONFIG]', '') # try and make the path for URL evaluation relative to the node's path aList = g.get_directives_dict_list(p) path = c.scanAtPathDirectives(aList) if p.h.startswith('@'): # see if it's a @<file> node of some sort nodepath = p.h.split(None, 1)[-1] nodepath = g.os_path_join(path, nodepath) if not g.os_path_isdir(nodepath): # remove filename nodepath = g.os_path_dirname(nodepath) if g.os_path_isdir(nodepath): # append if it's a directory path = nodepath self.webview.setHtml(data, QtCore.QUrl.fromLocalFile(path + "/"))
def select_node(self, tag, kwargs): c = kwargs['c'] if c != self.c: return p = kwargs['new_p'] self.v = p.v # to ensure unselect_node is working on the right node # currently (20130814) insert doesn't trigger unselect/select, but # even if it did, this would be safest data = self.template if p.b.startswith('<'): # already rich text, probably content = p.b self.was_rich = True else: self.was_rich = p.b.strip() == '' # put anything except whitespace in a <pre/> content = "<pre>%s</pre>" % p.b if not self.was_rich else '' data = data.replace('[CONTENT]', content) # replace textarea with CKEditor, with or without config. if self.config: data = data.replace('[CONFIG]', ', '+self.config) else: data = data.replace('[CONFIG]', '') # try and make the path for URL evaluation relative to the node's path aList = g.get_directives_dict_list(p) path = c.scanAtPathDirectives(aList) if p.h.startswith('@'): # see if it's a @<file> node of some sort nodepath = p.h.split(None, 1)[-1] nodepath = g.os_path_join(path, nodepath) if not g.os_path_isdir(nodepath): # remove filename nodepath = g.os_path_dirname(nodepath) if g.os_path_isdir(nodepath): # append if it's a directory path = nodepath self.webview.setHtml(data, QtCore.QUrl.fromLocalFile(path+"/"))
def doSubprocessTable (): if 1: pythonDir = g.os_path_dirname(sys.executable) idle = g.os_path_abspath(g.os_path_join(pythonDir,'Lib','idlelib','idle.pyw')) table = ( ("Idle", "Alt+Ctrl+I", ("subprocess.Popen", # ["pythonw", "C:/Python24/Lib/idlelib/idle.pyw"], ".py")), ["pythonw", idle], ".py")), ("Word", "Alt+Ctrl+W", ("subprocess.Popen", "C:/Program Files/Microsoft Office/Office/WINWORD.exe", None)), ("WordPad", "Alt+Ctrl+T", ("subprocess.Popen", "C:/Program Files/Windows NT/Accessories/wordpad.exe", None)), ) else: # Jim Sizelove's table table = ( ("Emacs", "Alt+Ctrl+E", ("subprocess.Popen", "C:/Program Files/Emacs/bin/emacs.exe", None)), ("Gvim", "Alt+Ctrl+G", ("subprocess.Popen", ["C:/Program Files/Vim/vim63/gvim.exe", "--servername", "LEO", "--remote-silent"], None)), ("Idle", "Alt+Ctrl+I", ("subprocess.Popen", ["pythonw", "C:/Python24/Lib/idlelib/idle.pyw"], ".py")), ("NotePad", "Alt+Ctrl+N", ("os.startfile", None, ".txt")), ("PythonWin", "Alt+Ctrl+P", ("subprocess.Popen", "C:/Python24/Lib/site-packages/pythonwin/Pythonwin.exe", None)), ("WordPad", "Alt+Ctrl+W", ("subprocess.Popen", "C:/Program Files/Windows NT/Accessories/wordpad.exe", None)), ) return table
def create_commit_timestamp_json(after=False): ''' Create leo/core/commit_timestamp.json. This is called from @button make-leo in leoDist.leo, so get_version_from_git should always succeed. ''' trace = False and not g.unitTesting import shlex import subprocess import sys commit, date = get_version_from_git(short=False) if commit: base = g.app.loadDir if g.app else g.os_path_dirname(__file__) path = g.os_path_finalize_join(base, '..', 'core', 'commit_timestamp.json') f = open(path, 'w') if after: commit = 'after ' + commit d = {'date': date, 'hash': commit} json.dump(d, f) f.write('\n') if trace: g.trace() g.print_dict(d) f.flush() f.close() # Add commit_timestamp.json so it doesn't appear dirty. p = subprocess.Popen( shlex.split('git add leo/core/commit_timestamp.json'), stdout=subprocess.PIPE, # stderr=None if trace else subprocess.PIPE, # subprocess.DEVNULL is Python 3 only. shell=sys.platform.startswith('win'), ) out, err = p.communicate() if trace: g.trace(out) else: g.trace('can not create commit_timestamp.json')
def create_commit_timestamp_json(after=False): ''' Create leo/core/commit_timestamp.json. This is called from @button make-leo in leoDist.leo, so get_version_from_git should always succeed. ''' trace = False and not g.unitTesting import shlex import subprocess import sys commit, date = get_version_from_git(short=False) if commit: base = g.app.loadDir if g.app else g.os_path_dirname(__file__) path = g.os_path_finalize_join( base, '..', 'core', 'commit_timestamp.json') f = open(path, 'w') if after: commit = 'after ' + commit d = {'date': date, 'hash': commit} json.dump(d, f) f.write('\n') if trace: g.trace() g.print_dict(d) f.flush() f.close() # Add commit_timestamp.json so it doesn't appear dirty. p = subprocess.Popen( shlex.split('git add leo/core/commit_timestamp.json'), stdout=subprocess.PIPE, # stderr=None if trace else subprocess.PIPE, # subprocess.DEVNULL is Python 3 only. shell=sys.platform.startswith('win'), ) out, err = p.communicate() if trace: g.trace(out) else: g.trace('can not create commit_timestamp.json')
def replaceFileWithString(self, fn, s): '''Replace the file with s if s is different from theFile's contents. Return True if theFile was changed. ''' c = self.c x = self exists = g.os_path_exists(fn) if exists: # Read the file. Return if it is the same. s2, e = g.readFileIntoString(fn) if s2 is None: return False if s == s2: report = c.config.getBool('report_unchanged_files', default=True) if report and not g.unitTesting: g.es('unchanged:', fn) return False # Issue warning if directory does not exist. theDir = g.os_path_dirname(fn) if theDir and not g.os_path_exists(theDir): if not g.unitTesting: x.error('not written: %s directory not found' % fn) return False # Replace the file. try: f = open(fn, 'wb') # 2011/09/09: Use self.encoding. f.write(g.toEncodedString(s, encoding=self.encoding)) f.close() if not g.unitTesting: if exists: g.es('wrote:', fn) else: g.es('created:', fn) return True except IOError: x.error('unexpected exception writing file: %s' % (fn)) g.es_exception() return False
def findDebugger(self): """Find the winpdb debugger.""" c = self.c pythonDir = g.os_path_dirname(sys.executable) debugger_path = c.expand_path_expression( c.config.getString('debugger-path')) debuggers = ( # #1431: only expand path expression in @string debugger-path. debugger_path or '@string debugger-path', g.os_path_join(pythonDir, 'Lib', 'site-packages', 'winpdb.py'), # winpdb 1.1.2 or newer. g.os_path_join(pythonDir, 'scripts', '_winpdb.py'), # Older version. ) for debugger in debuggers: if debugger: debugger = g.os_path_finalize(debugger) if g.os_path_exists(debugger): return debugger # g.es_print('debugger does not exist:', debugger) g.es_print('winpdb not found in...') for z in debuggers: print(z) return None
def run(theDir,fn,rpython=False): '''Run pylint on fn.''' fn = os.path.join('leo',theDir,fn) rc_fn = os.path.abspath(os.path.join('leo','test','pylint-leo-rc.txt')) # print('run:scope:%s' % scope) fn = os.path.abspath(fn) if not fn.endswith('.py'): fn = fn+'.py' if not os.path.exists(rc_fn): print('pylint rc file not found:',rc_fn) return if not os.path.exists(fn): print('file not found:',fn) return # Report the file name and one level of directory. 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))) # Create the required args. args = ','.join([ "fn=r'%s'" % (fn), "rc=r'%s'" % (rc_fn), ]) if scope == 'stc-test': # The --tt option. # Report that Sherlock is enabled. print('pylint-leo.py --tt: enabling Sherlock traces') print('pylint-leo.py --tt: patterns contained in plyint-leo.py') # Report the source code. s = open(fn).read() print('pylint-leo.py: source:\n\n%s\n' % s) # Add the optional Sherlock args. dots = True patterns=[ #@+<< Sherlock patterns for pylint >> #@+node:ekr.20130111060235.10182: *3* << Sherlock patterns for pylint >> # Note: A leading * is never valid: change to .* '+.*infer*', # '+.*infer_name', '+.*infer_stmts', '+YES::__init__', ###'+TypeChecker::add_message', # '+.*add_message', # '+PyLinter::add_message', # '+TextReporter::add_message' # '+.*visit*', # '+TypeChecker::visit_getattr', # '+.*visit_class', # '+Basic*::visit_*', # '+.*__init__', # '+Instance::__init__', # '+Class::__init__', # '+Module::__init__', # '+Function::__init__', ###'+:.*typecheck.py', ###'+:.*inference.py', ###'+:.*variables.py', ###### Old traces # '+:.*bases.py', # '+.*path_raise_wrapper', # Enable everything. # # '+.*', # # Disable entire files. # # '-:.*\\lib\\.*', # Disables everything. # # Pylint files. # #'-:.*base.py', # #'-:.*bases.py', # '-:.*builder.py', # '-:.*__init__.py', # '-:.*format.py', # '-:.*interface.py', # implements # '-:.*rebuilder.py', # #'-:.*scoped_nodes', # # General library files. # '-:.*leoGlobals.py', # '-:.*codecs.py', # '-:.*config.py', # '-:.*configuration.py', # '-:.*ConfigParser.py', # '-:.*copy\.py', # '-:.*gettext.py', # '-:.*genericpath.py', # '-:.*graph.py', # '-:.*locale.py', # '-:.*optik_ext.py', # '-:.*optparse.py', # '-:.*os.py', # '-:.*ntpath.py', # '-:.*pickle.py', # '-:.*re.py', # '-:.*similar.py', # '-:.*shlex.py', # '-:.*sre_compile.py', # '-:.*sre_parse.py', # '-:.*string_escape.py', # '-:.*text.py', # '-:.*threading.py', # '-:.*tokenize.py', # '-:.*utils.py', # # Enable entire files. # # '+:.*base.py', # # '+:.*bases.py', # # '+:.*classes.py', # # '+:.*design_analysis.py', # # '+:.*format.py', # # '+:.*inference.py', # # '+:.*logging.py', # # '+:.*mixins.py', # # '+:.*newstyle.py', # # '+:.*node_classes.py', # # '+:.*protocols.py', # # '+:.*scoped_nodes.py', # # '+:.*typecheck.py', # # '+:.*variables.py', # # Disable individual methods. # '-close', # __init__.py # '-collect_block_lines', '-\<genexpr\>','-.*option.*','-.*register_checker','-set_reporter', # lint.py # '-frame','-root','-scope', # scoped_nodes # '-register', # various files. # # '-abspath','-normpath','-isstring','-normalize', # # '-splitext','-_splitext','-splitdrive','-splitstrip', # # '-.*option.*','-get','-set_option', # # '-unquote','-convert','-interpolate','-_call_validator', # compile stuff. # # '-_compile.*','-compile_.*','-_code','-identifyfunction', # compile stuff. # # '-_parse.*','-set_parser','-set_conflict_handler', # # '-append','-match', # # '-isbasestring', # # '-save.*','-memoize','-put', # # '-persistent_id', # # '-__next', # # '-nodes_of_class', # # '-__.*', # # '-_check.*', # # '-_.*', # # '-load_.*', #@-<< Sherlock patterns for pylint >> #@afterref ] show_return = True stats_patterns = [ #@+<< Sherlock stats patterns for pylint >> #@+node:ekr.20140327164521.16846: *3* << Sherlock stats patterns for pylint >> # '+.*__init__', # astroid.bases.py '+BoundMethod::__init__', '+InferenceContext::__init__', '+Instance::__init__', '+UnboundMethod::__init__', # astroid.node_classes.py '+Arguments::__init__', '+CallFunc::__init__', '+Const::__init__', # astroid.scoped_nods.py '+Class::__init__', '+Function::__init__', '+Module::__init__', #@-<< Sherlock stats patterns for pylint >> #@afterref ] verbose = True args = args + ',' + ','.join([ 'dots=%s' % (dots), 'patterns=%s' % (patterns), 'sherlock=True', 'show_return=%s' % (show_return), 'stats_patterns=%s' % (stats_patterns), 'verbose=%s' % (verbose), ]) # Execute the command in a separate process. command = '%s -c "import leo.core.leoGlobals as g; g.run_pylint(%s)"' % ( sys.executable,args) g.execute_shell_commands(command)
#@-others def main(src, dest): print('src', src) print('dest', dest) root = get_leo_data(g.readFileIntoEncodedString(src)) root.gnx = 'hidden-root-vnode-gnx' vns, seq = walk_tree(root) data = vnode_data(vns, seq[1:]) # skip hidden root with sqlite3.connect(dest) as conn: resetdb(conn) conn.executemany(sqls('insert-vnode'), data) conn.commit() acc = [] settings_harvester(root, [], acc) for gnx, kind, name, value, cond in acc: if kind == g.u('data'): value = repr(value)[:30] print(cond or "always", kind, name, pprint.pformat(value)) if __name__ == '__main__': src = g.os_path_finalize_join(g.os_path_dirname(__file__), '../config/myLeoSettings.leo') if len(sys.argv) > 1: src = sys.argv[1] dest = src[:-3] + 'db' main(src, dest) print('ok') #@-leo
def main(src, dest): print('src', src) print('dest', dest) root = get_leo_data(g.readFileIntoEncodedString(src)) root.gnx = 'hidden-root-vnode-gnx' vns, seq = walk_tree(root) data = vnode_data(vns, seq[1:]) # skip hidden root with sqlite3.connect(dest) as conn: resetdb(conn) conn.executemany(sqls('insert-vnode'), data) conn.commit() acc = [] settings_harvester(root, [], acc) for gnx, kind, name, value, cond in acc: if kind == g.u('data'): value = repr(value)[:30] print(cond or "always", kind, name, pprint.pformat(value)) if __name__ == '__main__': src = g.os_path_finalize_join(g.os_path_dirname(__file__), '../config/myLeoSettings.leo') if len(sys.argv) > 1: src = sys.argv[1] dest = src[:-3] + 'db' main(src, dest) print('ok') #@-leo
def save(self, event=None, fileName=None): '''Save a Leo outline to a file.''' if False and g.app.gui.guiName() == 'curses': g.trace('===== Save disabled in curses gui =====') return c = self p = c.p # Do this now: w may go away. w = g.app.gui.get_focus(c) inBody = g.app.gui.widget_name(w).startswith('body') if inBody: p.saveCursorAndScroll() if g.unitTesting and g.app.unitTestDict.get('init_error_dialogs') is not None: # A kludge for unit testing: # indicated that c.init_error_dialogs and c.raise_error_dialogs # will be called below, *without* actually saving the .leo file. c.init_error_dialogs() c.raise_error_dialogs(kind='write') return if g.app.disableSave: g.es("save commands disabled", color="purple") return c.init_error_dialogs() # 2013/09/28: use the fileName keyword argument if given. # This supports the leoBridge. # Make sure we never pass None to the ctor. if fileName: c.frame.title = g.computeWindowTitle(fileName) c.mFileName = fileName if not c.mFileName: c.frame.title = "" c.mFileName = "" if c.mFileName: # Calls c.setChanged(False) if no error. g.app.syntax_error_files = [] c.fileCommands.save(c.mFileName) c.syntaxErrorDialog() else: root = c.rootPosition() if not root.next() and root.isAtEditNode(): # There is only a single @edit node in the outline. # A hack to allow "quick edit" of non-Leo files. # See https://bugs.launchpad.net/leo-editor/+bug/381527 fileName = None # Write the @edit node if needed. if root.isDirty(): c.atFileCommands.writeOneAtEditNode(root, toString=False, force=True) c.setChanged(False) else: fileName = ''.join(c.k.givenArgs) if not fileName: fileName = g.app.gui.runSaveFileDialog(c, initialfile=c.mFileName, title="Save", filetypes=[g.fileFilters('LEOFILES')], defaultextension=g.defaultLeoFileExtension(c)) c.bringToFront() if fileName: # Don't change mFileName until the dialog has suceeded. c.mFileName = g.ensure_extension(fileName, g.defaultLeoFileExtension(c)) c.frame.title = c.computeWindowTitle(c.mFileName) c.frame.setTitle(c.computeWindowTitle(c.mFileName)) # 2013/08/04: use c.computeWindowTitle. c.openDirectory = c.frame.openDirectory = g.os_path_dirname(c.mFileName) # Bug fix in 4.4b2. if g.app.qt_use_tabs and hasattr(c.frame, 'top'): c.frame.top.leo_master.setTabName(c, c.mFileName) c.fileCommands.save(c.mFileName) g.app.recentFilesManager.updateRecentFiles(c.mFileName) g.chdir(c.mFileName) # Done in FileCommands.save. # c.redraw_after_icons_changed() c.raise_error_dialogs(kind='write') # *Safely* restore focus, without using the old w directly. if inBody: c.bodyWantsFocus() p.restoreCursorAndScroll() else: c.treeWantsFocus()
def shadowDirName(self, filename): """Return the directory for the shadow file corresponding to filename.""" x = self return g.os_path_dirname(x.shadowPathName(filename))
def run(theDir, fn, silent, rpython=False): '''Run pylint on fn.''' global rc_warning_given # A little hack. theDir is empty for the -f option. if theDir: fn = os.path.join('leo', theDir, fn) rc_fn = os.path.abspath(os.path.join('leo', 'test', 'pylint-leo-rc.txt')) fn = os.path.abspath(fn) if not fn.endswith('.py'): fn = fn + '.py' if not os.path.exists(rc_fn): if not rc_warning_given: rc_warning_given = True print('pylint rc file not found: %s' % (rc_fn)) if not os.path.exists(fn): print('file not found: %s' % (fn)) return 0.0 # Report the file name and one level of directory. path = g.os_path_dirname(fn) dirs = path.split(os.sep) theDir = dirs and dirs[-1] or '' if not silent: print('pylint-leo.py: %s%s%s' % (theDir, os.sep, g.shortFileName(fn))) # Create the required args. args = ','.join([ "fn=r'%s'" % (fn), "rc=r'%s'" % (rc_fn), ]) if scope == 'stc-test': # The --tt option. # Report that Sherlock is enabled. print('pylint-leo.py --tt: enabling Sherlock traces') print('pylint-leo.py --tt: patterns contained in plyint-leo.py') # Report the source code. s = open(fn).read() print('pylint-leo.py: source:\n\n%s\n' % s) # Add the optional Sherlock args. dots = True patterns = [ #@+<< Sherlock patterns for pylint >> #@+node:ekr.20130111060235.10182: *3* << Sherlock patterns for pylint >> #@@nobeautify # Note: A leading * is never valid: change to .* '+.*infer*', # '+.*infer_name', '+.*infer_stmts', '+YES::__init__', # '+TypeChecker::add_message', # '+.*add_message', # '+PyLinter::add_message', # '+TextReporter::add_message' # '+.*visit*', # '+TypeChecker::visit_getattr', # '+.*visit_class', # '+Basic*::visit_*', # '+.*__init__', # '+Instance::__init__', # '+Class::__init__', # '+Module::__init__', # '+Function::__init__', # '+:.*typecheck.py', # '+:.*inference.py', # '+:.*variables.py', # Old traces # '+:.*bases.py', # '+.*path_raise_wrapper', # Enable everything. # # '+.*', # # Disable entire files. # # '-:.*\\lib\\.*', # Disables everything. # # Pylint files. # #'-:.*base.py', # #'-:.*bases.py', # '-:.*builder.py', # '-:.*__init__.py', # '-:.*format.py', # '-:.*interface.py', # implements # '-:.*rebuilder.py', # #'-:.*scoped_nodes', # # General library files. # '-:.*leoGlobals.py', # '-:.*codecs.py', # '-:.*config.py', # '-:.*configuration.py', # '-:.*ConfigParser.py', # '-:.*copy\.py', # '-:.*gettext.py', # '-:.*genericpath.py', # '-:.*graph.py', # '-:.*locale.py', # '-:.*optik_ext.py', # '-:.*optparse.py', # '-:.*os.py', # '-:.*ntpath.py', # '-:.*pickle.py', # '-:.*re.py', # '-:.*similar.py', # '-:.*shlex.py', # '-:.*sre_compile.py', # '-:.*sre_parse.py', # '-:.*string_escape.py', # '-:.*text.py', # '-:.*threading.py', # '-:.*tokenize.py', # '-:.*utils.py', # # Enable entire files. # # '+:.*base.py', # # '+:.*bases.py', # # '+:.*classes.py', # # '+:.*design_analysis.py', # # '+:.*format.py', # # '+:.*inference.py', # # '+:.*logging.py', # # '+:.*mixins.py', # # '+:.*newstyle.py', # # '+:.*node_classes.py', # # '+:.*protocols.py', # # '+:.*scoped_nodes.py', # # '+:.*typecheck.py', # # '+:.*variables.py', # # Disable individual methods. # '-close', # __init__.py # '-collect_block_lines', '-\<genexpr\>','-.*option.*','-.*register_checker','-set_reporter', # lint.py # '-frame','-root','-scope', # scoped_nodes # '-register', # various files. # # '-abspath','-normpath','-isstring','-normalize', # # '-splitext','-_splitext','-splitdrive','-splitstrip', # # '-.*option.*','-get','-set_option', # # '-unquote','-convert','-interpolate','-_call_validator', # compile stuff. # # '-_compile.*','-compile_.*','-_code','-identifyfunction', # compile stuff. # # '-_parse.*','-set_parser','-set_conflict_handler', # # '-append','-match', # # '-isbasestring', # # '-save.*','-memoize','-put', # # '-persistent_id', # # '-__next', # # '-nodes_of_class', # # '-__.*', # # '-_check.*', # # '-_.*', # # '-load_.*', #@-<< Sherlock patterns for pylint >> ] show_return = True stats_patterns = [ #@+<< Sherlock stats patterns for pylint >> #@+node:ekr.20140327164521.16846: *3* << Sherlock stats patterns for pylint >> #@@nobeautify # '+.*__init__', # astroid.bases.py '+BoundMethod::__init__', '+InferenceContext::__init__', '+Instance::__init__', '+UnboundMethod::__init__', # astroid.node_classes.py '+Arguments::__init__', '+CallFunc::__init__', '+Const::__init__', # astroid.scoped_nods.py '+Class::__init__', '+Function::__init__', '+Module::__init__', #@-<< Sherlock stats patterns for pylint >> ] verbose = True args = args + ',' + ','.join([ 'dots=%s' % (dots), 'patterns=%s' % (patterns), 'sherlock=True', 'show_return=%s' % (show_return), 'stats_patterns=%s' % (stats_patterns), 'verbose=%s' % (verbose), ]) # Execute the command in a separate process. 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() return t2 - t1
def save(self, event=None, fileName=None): """ Save a Leo outline to a file, using the existing file name unless the fileName kwarg is given. kwarg: a file name, for use by scripts using Leo's bridge. """ c = self p = c.p # Do this now: w may go away. w = g.app.gui.get_focus(c) inBody = g.app.gui.widget_name(w).startswith('body') if inBody: p.saveCursorAndScroll() if g.app.disableSave: g.es("save commands disabled", color="purple") return c.init_error_dialogs() # 2013/09/28: use the fileName keyword argument if given. # This supports the leoBridge. # Make sure we never pass None to the ctor. if fileName: c.frame.title = g.computeWindowTitle(fileName) c.mFileName = fileName if not c.mFileName: c.frame.title = "" c.mFileName = "" if c.mFileName: # Calls c.clearChanged() if no error. g.app.syntax_error_files = [] c.fileCommands.save(c.mFileName) c.syntaxErrorDialog() else: root = c.rootPosition() if not root.next() and root.isAtEditNode(): # There is only a single @edit node in the outline. # A hack to allow "quick edit" of non-Leo files. # See https://bugs.launchpad.net/leo-editor/+bug/381527 fileName = None # Write the @edit node if needed. if root.isDirty(): c.atFileCommands.writeOneAtEditNode(root) c.clearChanged() # Clears all dirty bits. else: fileName = ''.join(c.k.givenArgs) if not fileName: fileName = g.app.gui.runSaveFileDialog( c, title="Save", filetypes=[ ("Leo files", "*.leo *.db"), ], defaultextension=g.defaultLeoFileExtension(c)) c.bringToFront() if fileName: # Don't change mFileName until the dialog has suceeded. c.mFileName = g.ensure_extension(fileName, g.defaultLeoFileExtension(c)) c.frame.title = c.computeWindowTitle(c.mFileName) c.frame.setTitle(c.computeWindowTitle(c.mFileName)) c.openDirectory = c.frame.openDirectory = g.os_path_dirname( c.mFileName) if hasattr(c.frame, 'top'): c.frame.top.leo_master.setTabName(c, c.mFileName) c.fileCommands.save(c.mFileName) g.app.recentFilesManager.updateRecentFiles(c.mFileName) g.chdir(c.mFileName) # FileCommands.save calls c.redraw_after_icons_changed() c.raise_error_dialogs(kind='write') # *Safely* restore focus, without using the old w directly. if inBody: c.bodyWantsFocus() p.restoreCursorAndScroll() else: c.treeWantsFocus()
def saveAs(self, event=None, fileName=None): """ Save a Leo outline to a file, prompting for a new filename unless the fileName kwarg is given. kwarg: a file name, for use by file-save-as-zipped, file-save-as-unzipped and scripts using Leo's bridge. """ c = self p = c.p # Do this now: w may go away. w = g.app.gui.get_focus(c) inBody = g.app.gui.widget_name(w).startswith('body') if inBody: p.saveCursorAndScroll() if g.app.disableSave: g.es("save commands disabled", color="purple") return c.init_error_dialogs() # 2013/09/28: add fileName keyword arg for leoBridge scripts. if fileName: c.frame.title = g.computeWindowTitle(fileName) c.mFileName = fileName # Make sure we never pass None to the ctor. if not c.mFileName: c.frame.title = "" if not fileName: fileName = ''.join(c.k.givenArgs) if not fileName: fileName = g.app.gui.runSaveFileDialog( c, initialfile=c.mFileName, title="Save As", filetypes=[ ("Leo files", "*.leo *.db"), ], defaultextension=g.defaultLeoFileExtension(c)) c.bringToFront() if fileName: # Fix bug 998090: save file as doesn't remove entry from open file list. if c.mFileName: g.app.forgetOpenFile(c.mFileName) # Don't change mFileName until the dialog has suceeded. c.mFileName = g.ensure_extension(fileName, g.defaultLeoFileExtension(c)) # Part of the fix for https://bugs.launchpad.net/leo-editor/+bug/1194209 c.frame.title = title = c.computeWindowTitle(c.mFileName) c.frame.setTitle(title) # 2013/08/04: use c.computeWindowTitle. c.openDirectory = c.frame.openDirectory = g.os_path_dirname( c.mFileName) # Bug fix in 4.4b2. # Calls c.clearChanged() if no error. if g.app.qt_use_tabs and hasattr(c.frame, 'top'): c.frame.top.leo_master.setTabName(c, c.mFileName) c.fileCommands.saveAs(c.mFileName) g.app.recentFilesManager.updateRecentFiles(c.mFileName) g.chdir(c.mFileName) # Done in FileCommands.saveAs. # c.redraw_after_icons_changed() c.raise_error_dialogs(kind='write') # *Safely* restore focus, without using the old w directly. if inBody: c.bodyWantsFocus() p.restoreCursorAndScroll() else: c.treeWantsFocus()
def compare_directories(self, path1, path2): # Ignore everything except the directory name. dir1 = g.os_path_dirname(path1) dir2 = g.os_path_dirname(path2) dir1 = g.os_path_normpath(dir1) dir2 = g.os_path_normpath(dir2) if dir1 == dir2: return self.show("Please pick distinct directories.") try: list1 = os.listdir(dir1) except Exception: return self.show("invalid directory:" + dir1) try: list2 = os.listdir(dir2) except Exception: return self.show("invalid directory:" + dir2) if self.outputFileName: self.openOutputFile() ok = self.outputFileName is None or self.outputFile if not ok: return None # Create files and files2, the lists of files to be compared. files1 = [] files2 = [] for f in list1: junk, ext = g.os_path_splitext(f) if self.limitToExtension: if ext == self.limitToExtension: files1.append(f) else: files1.append(f) for f in list2: junk, ext = g.os_path_splitext(f) if self.limitToExtension: if ext == self.limitToExtension: files2.append(f) else: files2.append(f) # Compare the files and set the yes, no and missing lists. yes = []; no = []; missing1 = []; missing2 = [] for f1 in files1: head, f2 = g.os_path_split(f1) if f2 in files2: try: name1 = g.os_path_join(dir1, f1) name2 = g.os_path_join(dir2, f2) val = filecmp.cmp(name1, name2, 0) if val: yes.append(f1) else: no.append(f1) except Exception: self.show("exception in filecmp.cmp") g.es_exception() missing1.append(f1) else: missing1.append(f1) for f2 in files2: head, f1 = g.os_path_split(f2) if f1 not in files1: missing2.append(f1) # Print the results. for kind, files in ( ("----- matches --------", yes), ("----- mismatches -----", no), ("----- not found 1 ------", missing1), ("----- not found 2 ------", missing2), ): self.show(kind) for f in files: self.show(f) if self.outputFile: self.outputFile.close() self.outputFile = None return None # To keep pychecker happy.
def dirName(self, filename): """Return the directory for filename.""" x = self return g.os_path_dirname(x.pathName(filename))
def compare_directories(self, path1, path2): # Ignore everything except the directory name. dir1 = g.os_path_dirname(path1) dir2 = g.os_path_dirname(path2) dir1 = g.os_path_normpath(dir1) dir2 = g.os_path_normpath(dir2) if dir1 == dir2: return self.show("Please pick distinct directories.") try: list1 = os.listdir(dir1) except: return self.show("invalid directory:" + dir1) try: list2 = os.listdir(dir2) except: return self.show("invalid directory:" + dir2) if self.outputFileName: self.openOutputFile() ok = self.outputFileName == None or self.outputFile if not ok: return None # Create files and files2, the lists of files to be compared. files1 = [] files2 = [] for f in list1: junk, ext = g.os_path_splitext(f) if self.limitToExtension: if ext == self.limitToExtension: files1.append(f) else: files1.append(f) for f in list2: junk, ext = g.os_path_splitext(f) if self.limitToExtension: if ext == self.limitToExtension: files2.append(f) else: files2.append(f) # Compare the files and set the yes, no and missing lists. yes = [] no = [] missing1 = [] missing2 = [] for f1 in files1: head, f2 = g.os_path_split(f1) if f2 in files2: try: name1 = g.os_path_join(dir1, f1) name2 = g.os_path_join(dir2, f2) val = filecmp.cmp(name1, name2, 0) if val: yes.append(f1) else: no.append(f1) except: self.show("exception in filecmp.cmp") g.es_exception() missing1.append(f1) else: missing1.append(f1) for f2 in files2: head, f1 = g.os_path_split(f2) if f1 not in files1: missing2.append(f1) # Print the results. for kind, files in ( ("----- matches --------", yes), ("----- mismatches -----", no), ("----- not found 1 ------", missing1), ("----- not found 2 ------", missing2), ): self.show(kind) for f in files: self.show(f) if self.outputFile: self.outputFile.close() self.outputFile = None return None # To keep pychecker happy.
def __init__(self, owner, logTab=True): self.owner = owner QtWidgets.QWidget.__init__(self) uiPath = g.os_path_join(g.app.leoDir, 'plugins', 'ToDo.ui') # change dir to get themed icons theme = g.app.config.getString('color_theme') if theme: testPath = g.os_path_join( g.app.homeLeoDir, 'themes', theme, 'Icons', 'cleo') if g.os_path_exists(testPath): iconPath = g.os_path_dirname(testPath) else: testPath = g.os_path_join( g.app.loadDir, '..', 'themes', theme, 'Icons', 'cleo') if g.os_path_exists(testPath): iconPath = g.os_path_dirname(testPath) else: iconPath = g.os_path_join(g.app.leoDir, 'Icons') else: iconPath = g.os_path_join(g.app.leoDir, 'Icons') os.chdir(iconPath) form_class, base_class = uic.loadUiType(uiPath) if logTab: self.owner.c.frame.log.createTab('Task', widget = self) self.UI = form_class() self.UI.setupUi(self) u = self.UI o = self.owner self.menu = QtWidgets.QMenu() self.populateMenu(self.menu, o) u.butMenu.setMenu(self.menu) if isQt5: u.butHelp.clicked.connect(lambda checked: o.showHelp()) u.butClrProg.clicked.connect(lambda checked: o.progress_clear()) u.butClrTime.clicked.connect(lambda checked: o.clear_time_req()) u.butPriClr.clicked.connect(lambda checked: o.priority_clear()) # if live update is too slow change valueChanged(*) to editingFinished() u.spinTime.valueChanged.connect( lambda v: o.set_time_req(val=u.spinTime.value())) u.spinProg.valueChanged.connect( lambda v: o.set_progress(val=u.spinProg.value())) else: self.connect(u.butHelp, QtCore.SIGNAL("clicked()"), o.showHelp) self.connect(u.butClrProg, QtCore.SIGNAL("clicked()"), o.progress_clear) self.connect(u.butClrTime, QtCore.SIGNAL("clicked()"), o.clear_time_req) self.connect(u.butPriClr, QtCore.SIGNAL("clicked()"), o.priority_clear) # if live update is too slow change valueChanged(*) to editingFinished() self.connect(u.spinTime, QtCore.SIGNAL("valueChanged(double)"), lambda v: o.set_time_req(val=u.spinTime.value())) self.connect(u.spinProg, QtCore.SIGNAL("valueChanged(int)"), lambda v: o.set_progress(val=u.spinProg.value())) u.dueDateEdit.dateChanged.connect( lambda v: o.set_due_date(val=u.dueDateEdit.date())) u.dueTimeEdit.timeChanged.connect( lambda v: o.set_due_time(val=u.dueTimeEdit.time())) u.nxtwkDateEdit.dateChanged.connect( lambda v: o.set_due_date(val=u.nxtwkDateEdit.date(), field='nextworkdate')) u.nxtwkTimeEdit.timeChanged.connect( lambda v: o.set_due_time(val=u.nxtwkTimeEdit.time(), field='nextworktime')) u.dueDateToggle.stateChanged.connect( lambda v: o.set_due_date(val=u.dueDateEdit.date(), mode='check')) u.dueTimeToggle.stateChanged.connect( lambda v: o.set_due_time(val=u.dueTimeEdit.time(), mode='check')) u.nxtwkDateToggle.stateChanged.connect( lambda v: o.set_due_date(val=u.nxtwkDateEdit.date(), mode='check', field='nextworkdate')) u.nxtwkTimeToggle.stateChanged.connect( lambda v: o.set_due_time(val=u.nxtwkTimeEdit.time(), mode='check', field='nextworktime')) for but in ["butPri1", "butPri6", "butPriChk", "butPri2", "butPri4", "butPri5", "butPri8", "butPri9", "butPri0", "butPriToDo", "butPriXgry", "butPriBang", "butPriX", "butPriQuery", "butPriBullet", "butPri7", "butPri3"]: w = getattr(u, but) # w.property() seems to give QVariant in python 2.x and int in 3.x!? try: pri = int(w.property('priority')) except (TypeError, ValueError): try: pri, ok = w.property('priority').toInt() except (TypeError, ValueError): pri = -1 # pylint: disable=cell-var-from-loop def setter(pri=pri): o.setPri(pri) if isQt5: w.clicked.connect(lambda checked, setter=setter: setter()) else: self.connect(w, QtCore.SIGNAL("clicked()"), setter) offsets = self.owner.c.config.getData('todo_due_date_offsets') if not offsets: offsets = '+7 +0 +1 +2 +3 +4 +5 +6 +10 +14 +21 +28 +42 +60 +90 +120 +150 ' \ '>7 <7 <14 >14 <28 >28'.split() self.date_offset_default = int(offsets[0].strip('>').replace('<', '-')) offsets = sorted(set(offsets), key=lambda x: (x[0],int(x[1:].strip('>').replace('<', '-')))) u.dueDateOffset.addItems(offsets) u.dueDateOffset.setCurrentIndex(self.date_offset_default) if isQt5: self.UI.dueDateOffset.activated.connect( lambda v: o.set_date_offset(field='duedate')) else: self.connect(self.UI.dueDateOffset, QtCore.SIGNAL("activated(int)"), lambda v: o.set_date_offset(field='duedate')) u.nxtwkDateOffset.addItems(offsets) u.nxtwkDateOffset.setCurrentIndex(self.date_offset_default) if isQt5: self.UI.nxtwkDateOffset.activated.connect( lambda v: o.set_date_offset(field='nextworkdate')) else: self.connect(self.UI.nxtwkDateOffset, QtCore.SIGNAL("activated(int)"), lambda v: o.set_date_offset(field='nextworkdate')) self.setDueDate = self.make_func(self.UI.dueDateEdit, self.UI.dueDateToggle, 'setDate', datetime.date.today() + datetime.timedelta(self.date_offset_default)) self.setDueTime = self.make_func(self.UI.dueTimeEdit, self.UI.dueTimeToggle, 'setTime', datetime.datetime.now().time()) self.setNextWorkDate = self.make_func(self.UI.nxtwkDateEdit, self.UI.nxtwkDateToggle, 'setDate', datetime.date.today() + datetime.timedelta(self.date_offset_default)) self.setNextWorkTime = self.make_func(self.UI.nxtwkTimeEdit, self.UI.nxtwkTimeToggle, 'setTime', datetime.datetime.now().time()) if isQt5: self.UI.butDetails.clicked.connect( lambda checked: self.UI.frmDetails.setVisible(not self.UI.frmDetails.isVisible())) else: self.connect(self.UI.butDetails, QtCore.SIGNAL("clicked()"), lambda: self.UI.frmDetails.setVisible(not self.UI.frmDetails.isVisible())) if self.owner.c.config.getBool("todo_compact_interface"): self.UI.frmDetails.setVisible(False) if isQt5: self.UI.butNext.clicked.connect( lambda checked: self.owner.c.selectVisNext()) self.UI.butNextTodo.clicked.connect( lambda checked: self.owner.find_todo()) self.UI.butApplyDueOffset.clicked.connect( lambda checked: o.set_date_offset(field='duedate')) self.UI.butApplyOffset.clicked.connect( lambda checked: o.set_date_offset(field='nextworkdate')) else: self.connect(self.UI.butNext, QtCore.SIGNAL("clicked()"), lambda: self.owner.c.selectVisNext()) self.connect(self.UI.butNextTodo, QtCore.SIGNAL("clicked()"), self.owner.find_todo) self.connect(self.UI.butApplyDueOffset, QtCore.SIGNAL("clicked()"), lambda: o.set_date_offset(field='duedate')) self.connect(self.UI.butApplyOffset, QtCore.SIGNAL("clicked()"), lambda: o.set_date_offset(field='nextworkdate')) n = g.app.config.getInt("todo_calendar_n") cols = g.app.config.getInt("todo_calendar_cols") if n or cols: self.UI.dueDateEdit.calendarWidget().build(n or 3, cols or 3) self.UI.nxtwkDateEdit.calendarWidget().build(n or 3, cols or 3)
def _getpath(self, p): c = self.c path = g.fullPath(c, p) # #1914 # Use os.path.normpath to give system separators. return os.path.normpath(g.os_path_dirname(path)) # #1914
def __init__(self, owner, logTab=True): self.owner = owner QtGui.QWidget.__init__(self) uiPath = g.os_path_join(g.app.leoDir, 'plugins', 'ToDo.ui') # change dir to get themed icons theme = g.app.config.getString('color_theme') if theme: testPath = g.os_path_join( g.app.homeLeoDir, 'themes', theme, 'Icons', 'cleo') if g.os_path_exists(testPath): iconPath = g.os_path_dirname(testPath) else: testPath = g.os_path_join( g.app.loadDir, '..', 'themes', theme, 'Icons', 'cleo') if g.os_path_exists(testPath): iconPath = g.os_path_dirname(testPath) else: iconPath = g.os_path_join(g.app.leoDir, 'Icons') else: iconPath = g.os_path_join(g.app.leoDir, 'Icons') os.chdir(iconPath) form_class, base_class = uic.loadUiType(uiPath) if logTab: self.owner.c.frame.log.createTab('Task', widget = self) self.UI = form_class() self.UI.setupUi(self) u = self.UI o = self.owner self.menu = QtGui.QMenu() self.populateMenu(self.menu, o) u.butMenu.setMenu(self.menu) self.connect(u.butHelp, QtCore.SIGNAL("clicked()"), o.showHelp) self.connect(u.butClrProg, QtCore.SIGNAL("clicked()"), o.progress_clear) self.connect(u.butClrTime, QtCore.SIGNAL("clicked()"), o.clear_time_req) self.connect(u.butPriClr, QtCore.SIGNAL("clicked()"), o.priority_clear) # if live update is too slow change valueChanged(*) to editingFinished() self.connect(u.spinTime, QtCore.SIGNAL("valueChanged(double)"), lambda v: o.set_time_req(val=u.spinTime.value())) self.connect(u.spinProg, QtCore.SIGNAL("valueChanged(int)"), lambda v: o.set_progress(val=u.spinProg.value())) # can't work out SIGNAL() names u.dueDateEdit.dateChanged.connect( lambda v: o.set_due_date(val=u.dueDateEdit.date())) u.dueTimeEdit.timeChanged.connect( lambda v: o.set_due_time(val=u.dueTimeEdit.time())) u.dueDateToggle.stateChanged.connect( lambda v: o.set_due_date(val=u.dueDateEdit.date(), mode='check')) u.dueTimeToggle.stateChanged.connect( lambda v: o.set_due_time(val=u.dueTimeEdit.time(), mode='check')) # FIXME - move to ui design u.dueDateEdit.setEnabled(True) u.dueTimeEdit.setEnabled(True) for but in ["butPri1", "butPri6", "butPriChk", "butPri2", "butPri4", "butPri5", "butPri8", "butPri9", "butPri0", "butPriToDo", "butPriXgry", "butPriBang", "butPriX", "butPriQuery", "butPriBullet", "butPri7", "butPri3"]: w = getattr(u, but) # w.property() seems to give QVariant in python 2.x and int in 3.x!? try: pri = int(w.property('priority')) except (TypeError, ValueError): try: pri, ok = w.property('priority').toInt() except (TypeError, ValueError): pri = -1 def setter(pri=pri): o.setPri(pri) self.connect(w, QtCore.SIGNAL("clicked()"), setter) offsets = self.owner.c.config.getData('todo_due_date_offsets') if not offsets: offsets = '+7 +0 +1 +2 +3 +4 +5 +6 +10 +14 +21 +28 +42 +60 +90 +120 +150 ' \ '>7 <7 <14 >14 <28 >28'.split() self.date_offset_default = int(offsets[0].strip('>').replace('<', '-')) offsets = sorted(set(offsets), key=lambda x: (x[0],int(x[1:].strip('>').replace('<', '-')))) u.dueDateOffset.addItems(offsets) u.dueDateOffset.setCurrentIndex(self.date_offset_default) self.connect(self.UI.dueDateOffset, QtCore.SIGNAL("activated(int)"), lambda v: o.set_due_date_offset()) self.setDueDate = self.make_func(self.UI.dueDateEdit, self.UI.dueDateToggle, 'setDate', datetime.date.today() + datetime.timedelta(self.date_offset_default)) self.setDueTime = self.make_func(self.UI.dueTimeEdit, self.UI.dueTimeToggle, 'setTime', datetime.datetime.now().time()) self.connect(self.UI.butDetails, QtCore.SIGNAL("clicked()"), lambda: self.UI.frmDetails.setVisible(not self.UI.frmDetails.isVisible())) if self.owner.c.config.getBool("todo_compact_interface"): self.UI.frmDetails.setVisible(False) self.connect(self.UI.butNext, QtCore.SIGNAL("clicked()"), lambda: self.owner.c.selectVisNext()) self.connect(self.UI.butNextTodo, QtCore.SIGNAL("clicked()"), self.owner.find_todo)