def open_file(self, root): '''Open the the file in vim using c.openWith.''' c = self.c efc = g.app.externalFilesController # Common arguments. tab_arg = "-tab" if self.uses_tab else "" remote_arg = "--remote" + tab_arg + "-silent" args = [self.vim_exe, "--servername", "LEO", remote_arg] # No cursor arg. if self.entire_file: # vim-open-file args.append( '+0') # Go to first line of the file. This is an Ex command. assert root.isAnyAtFileNode(), root dir_ = g.setDefaultDirectory(c, root) fn = c.expand_path_expression(root.anyAtFileNodeName()) # #1341. fn = c.os_path_finalize_join(dir_, fn) else: # vim-open-node args.append(self.get_cursor_arg()) # Set the cursor position to the current line in the node. ext = 'txt' fn = efc.create_temp_file(c, ext, c.p) c_arg = '%s %s' % (' '.join(args), fn) command = 'subprocess.Popen(%s,shell=True)' % c_arg try: subprocess.Popen(c_arg, shell=True) except OSError: g.es_print(command) g.es_exception()
def listenToLog(self, event=None): ''' A socket listener, listening on localhost. See: https://docs.python.org/2/howto/logging-cookbook.html#sending-and-receiving-logging-events-across-a-network Start this listener first, then start the broadcaster. leo/plugins/cursesGui2.py is a typical broadcaster. ''' # Kill any previous listener. if g.app.log_listener: g.es_print('Killing previous listener') try: g.app.log_listener.kill() except Exception: g.es_exception() g.app.log_listener = None # Start a new listener. g.es_print('Starting log_listener.py') path = g.os_path_finalize_join(g.app.loadDir, '..', 'external', 'log_listener.py') g.app.log_listener = subprocess.Popen( [sys.executable, path], shell=False, universal_newlines=True, )
def parse_opml_file(self, fn): c = self.c if not fn or not fn.endswith('.opml'): return g.trace('bad file name: %s' % repr(fn)) c = self.c path = g.os_path_normpath(g.os_path_join(g.app.loadDir, fn)) try: f = open(path, 'rb') s = f.read() # type(s) is bytes for Python 3.x. s = self.cleanSaxInputString(s) except IOError: return g.trace('can not open %s' % path) # pylint:disable=catching-non-exception try: theFile = BytesIO(s) parser = xml.sax.make_parser() parser.setFeature(xml.sax.handler.feature_external_ges, 1) # Do not include external general entities. # The actual feature name is "http://xml.org/sax/features/external-general-entities" parser.setFeature(xml.sax.handler.feature_external_pes, 0) handler = SaxContentHandler(c, fn) parser.setContentHandler(handler) parser.parse(theFile) # expat does not support parseString sax_node = handler.getNode() except xml.sax.SAXParseException: g.error('error parsing', fn) g.es_exception() sax_node = None except Exception: g.error('unexpected exception parsing', fn) g.es_exception() sax_node = None return sax_node
def eventFilter(self, obj, event): c, k = self.c, self.c.k # # Handle non-key events first. if not self.c.p: return False # Startup. Let Qt handle the key event if 'events' in g.app.debug: self.traceEvent(obj, event) self.traceWidget(event) if self.doNonKeyEvent(event, obj): return False # Let Qt handle the non-key event. # # Ignore incomplete key events. if self.shouldIgnoreKeyEvent(event, obj): return False # Let Qt handle the key event. # # Generate a g.KeyStroke for k.masterKeyHandler. try: binding, ch = self.toBinding(event) if not binding: return False # Allow Qt to handle the key event. stroke = g.KeyStroke(binding=binding) if 'keys' in g.app.debug: g.trace('binding: %s, stroke: %s, char: %r' % (binding, stroke, ch)) # # Pass the KeyStroke to masterKeyHandler. key_event = self.createKeyEvent(event, c, self.w, ch, binding) k.masterKeyHandler(key_event) c.outerUpdate() except Exception: g.es_exception() return True
def export_outline(self, root, fn=None): ''' Entry point for export-jupyter-notebook Export the given .ipynb file. ''' self.root = root if not fn: fn = self.get_file_name() if not fn: return False try: nb = self.make_notebook() s = self.convert_notebook(nb) except Exception: g.es_exception() return False if not s: return False s = g.toEncodedString(s, encoding='utf-8', reportErrors=True) try: with open(fn, 'wb') as f: f.write(s) g.es_print('wrote: %s' % fn) except IOError: g.es_print('can not open: %s' % fn) return True
def compare_files(self, name1, name2): if name1 == name2: self.show("File names are identical.\nPlease pick distinct files.") return f1 = f2 = None try: f1 = self.doOpen(name1) f2 = self.doOpen(name2) if self.outputFileName: self.openOutputFile() ok = self.outputFileName == None or self.outputFile ok = g.choose(ok and ok != 0, 1, 0) if f1 and f2 and ok: # Don't compare if there is an error opening the output file. self.compare_open_files(f1, f2, name1, name2) except: self.show("exception comparing files") g.es_exception() try: if f1: f1.close() if f2: f2.close() if self.outputFile: self.outputFile.close() self.outputFile = None except: self.show("exception closing files") g.es_exception()
def OLD_parse_opml_file(self, inputFileName): if not inputFileName or not inputFileName.endswith(".opml"): return None c = self.c path = g.os_path_normpath(g.os_path_join(g.app.loadDir, inputFileName)) try: f = open(path) except IOError: g.trace("can not open %s" % path) return None try: try: node = None parser = xml.sax.make_parser() # Do not include external general entities. # The actual feature name is "http://xml.org/sax/features/external-general-entities" parser.setFeature(xml.sax.handler.feature_external_ges, 0) handler = SaxContentHandler(c, inputFileName) parser.setContentHandler(handler) parser.parse(f) node = handler.getNode() except xml.sax.SAXParseException: g.error("Error parsing %s" % (inputFileName)) g.es_exception() return None except Exception: g.error("Unexpected exception parsing %s" % (inputFileName)) g.es_exception() return None finally: f.close() return node
def start(self, script_tree, auto_run=False, delim='###', root=None): '''Start a demo. script_tree contains the demo scripts.''' import leo.core.leoNodes as leoNodes p = script_tree self.root = root and root.copy() self.script_root = script_tree and script_tree.copy() self.delete_widgets() self.auto_run = auto_run self.initial_geometry = self.get_top_geometry() # Setup may change this. if isinstance(p, leoNodes.Position): if p: self.script_list = self.create_script_list(p, delim) if self.script_list: try: self.setup(p) except Exception: g.es_exception() self.end() if auto_run: while self.script_i < len(self.script_list): g.app.gui.qtApp.processEvents() # Helps, but widgets are not deleted. self.next() else: self.next() else: g.trace('empty script tree at', p.h) else: g.trace('invalid p') else: g.trace('script_tree must be a position', repr(p)) self.end()
def open_file(self, root): '''Open the the file in vim using c.openWith.''' c = self.c efc = g.app.externalFilesController # Common arguments. tab_arg = "-tab" if self.uses_tab else "" remote_arg = "--remote" + tab_arg + "-silent" args = [self.vim_exe, "--servername", "LEO", remote_arg] # No cursor arg. if self.entire_file: # vim-open-file args.append('+0') # Go to first line of the file. This is an Ex command. assert root.isAnyAtFileNode(), root dir_ = g.setDefaultDirectory(c, root) fn = c.os_path_finalize_join(dir_, root.anyAtFileNodeName()) else: # vim-open-node args.append(self.get_cursor_arg()) # Set the cursor position to the current line in the node. ext = 'txt' fn = efc.create_temp_file(c, ext, c.p) c_arg = '%s %s' % (' '.join(args), fn) command = 'subprocess.Popen(%s,shell=True)' % c_arg try: subprocess.Popen(c_arg, shell=True) except OSError: g.es_print(command) g.es_exception()
def connect (self,fname): '''Connect to the server. Return True if the connection was established.''' trace = False and not g.unitTesting if trace: g.trace(fname,socket) if hasattr(socket,'AF_UNIX'): try: # pylint: disable=E1101 # E1101:LProtoClient.connect: Module 'socket' has no 'AF_UNIX' member self.socket = socket.socket(socket.AF_UNIX,socket.SOCK_STREAM) self.socket.connect(fname) return True except Exception: g.es_print('lproto.py: failed to connect!',fname) g.es_exception(full=False,c=None) return False else: try: host = '172.16.0.0' # host is a local address. port = 1 self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) self.socket.connect((host,port),) self.socket.connect(fname) return True except Exception: g.es_print('lproto.py: failed to connect! host: %s, port: %s' % ( host,port)) g.es_exception(full=False,c=None) return False
def connect(self, fname): '''Connect to the server. Return True if the connection was established.''' if hasattr(socket, 'AF_UNIX'): try: # pylint: disable=no-member # Module 'socket' has no 'AF_UNIX' member self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.socket.connect(fname) return True except Exception: g.es_print('lproto.py: failed to connect!', fname) g.es_exception(full=False, c=None) return False else: try: host = '172.16.0.0' # host is a local address. port = 1 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.connect((host, port),) self.socket.connect(fname) return True except Exception: g.es_print('lproto.py: failed to connect! host: %s, port: %s' % ( host, port)) g.es_exception(full=False, c=None) return False
def init_env(self): ''' Init c.abbrev_subst_env by executing the contents of the @data abbreviations-subst-env node. ''' c = self.c at = c.atFileCommands if c.abbrev_place_start and self.enabled: aList = self.subst_env script = [] for z in aList: # Compatibility with original design. if z.startswith('\\:'): script.append(z[2:]) else: script.append(z) script = ''.join(script) # Allow Leo directives in @data abbreviations-subst-env trees. import leo.core.leoNodes as leoNodes v = leoNodes.VNode(context=c) root = leoNodes.Position(v) # Similar to g.getScript. script = at.writeFromString(root=root, s=script, forcePythonSentinels=True, useSentinels=False) script = script.replace("\r\n", "\n") try: exec(script, c.abbrev_subst_env, c.abbrev_subst_env) except Exception: g.es('Error exec\'ing @data abbreviations-subst-env') g.es_exception() else: c.abbrev_subst_start = False
def prettyPrintNode(self, p): '''The driver for beautification: beautify a single node.''' # c = self.c if not should_beautify(p): # @nobeautify is in effect. return if not p.b: # Pretty printing might add text! return if not p.b.strip(): # Do this *after* we are sure @beautify is in effect. self.replace_body(p, '') return t1 = time.time() # Replace Leonine syntax with special comments. comment_string, s0 = comment_leo_lines(p) try: s1 = g.toEncodedString(s0) node1 = ast.parse(s1, filename='before', mode='exec') except IndentationError: self.skip_message('IndentationError', p) return except SyntaxError: self.skip_message('SyntaxError', p) return except Exception: g.es_exception() self.skip_message('Exception', p) return t2 = time.time() readlines = g.ReadLinesClass(s0).next tokens = list(tokenize.generate_tokens(readlines)) t3 = time.time() s2 = self.run(tokens) t4 = time.time() try: s2_e = g.toEncodedString(s2) node2 = ast.parse(s2_e, filename='before', mode='exec') ok = compare_ast(node1, node2) except Exception: g.es_exception() g.trace('Error in %s...\n%s' % (p.h, s2_e)) self.skip_message('BeautifierError', p) return if not ok: self.skip_message('BeautifierError', p) return t5 = time.time() # Restore the tags after the compare s3 = uncomment_leo_lines(comment_string, p, s2) self.replace_body(p, s3) # Update the stats self.n_input_tokens += len(tokens) self.n_output_tokens += len(self.code_list) self.n_strings += len(s3) self.parse_time += (t2 - t1) self.tokenize_time += (t3 - t2) self.beautify_time += (t4 - t3) self.check_time += (t5 - t4) self.total_time += (t5 - t1)
def adjustDefStart(self, s, i): '''A hook to allow the Python importer to adjust the start of a class or function to include decorators. ''' # Invariant: i does not change. # Invariant: start is the present return value. try: assert s[i] != '\n' start = j = g.find_line_start(s, i) if i > 0 else 0 # g.trace('entry',j,i,repr(s[j:i+10])) assert j == 0 or s[j - 1] == '\n' while j > 0: progress = j j1 = j = g.find_line_start(s, j - 2) # g.trace('line',repr(s[j:progress])) j = g.skip_ws(s, j) if not g.match(s, j, '@'): break k = g.skip_id(s, j + 1) word = s[j:k] # Leo directives halt the scan. if word and word in g.globalDirectiveList: break # A decorator. start = j = j1 assert j < progress # g.trace('**returns %s, %s' % (repr(s[start:i]),repr(s[i:i+20]))) return start except AssertionError: g.es_exception() return i
def open_index(self, idx_dir): global index_error_given if os.path.exists(idx_dir): try: return open_dir(idx_dir) except ValueError: if not index_error_given: index_error_given = True g.es_print('bigdash.py: exception in whoosh.open_dir') g.es_print('please remove this directory:', g.os_path_normpath(idx_dir)) return None # Doesn't work: open_dir apparently leaves resources open, # so shutil.rmtree(idx_dir) fails. # g.es_print('re-creating', repr(idx_dir)) # try: # import shutil # shutil.rmtree(idx_dir) # os.mkdir(idx_dir) # self.create() # return open_dir(idx_dir) # except Exception as why: # g.es_print(why) # return None else: try: os.mkdir(idx_dir) self.create() return open_dir(idx_dir) except Exception: g.es_exception() return None
def applyNodeAction(pScript, pClicked, c): script = g.getScript(c, pScript) if script: working_directory = os.getcwd() file_directory = c.frame.openDirectory os.chdir(file_directory) script += '\n' #Redirect output if c.config.redirect_execute_script_output_to_log_pane: g.redirectStdout() # Redirect stdout g.redirectStderr() # Redirect stderr try: namespace = { 'c': c, 'g': g, 'pClicked': pClicked, 'pScript': pScript, 'shellScriptInWindowNA': shellScriptInWindowNA } # exec script in namespace exec(script, namespace) #Unredirect output if c.config.redirect_execute_script_output_to_log_pane: g.restoreStderr() g.restoreStdout() except: #Unredirect output if c.config.redirect_execute_script_output_to_log_pane: g.restoreStderr() g.restoreStdout() g.es("exception in NodeAction plugin") g.es_exception(full=False, c=c) os.chdir(working_directory)
def open_file(self, root): '''Open the the file in vim using c.openWith.''' trace = (False or self.trace) and not g.unitTesting c = self.c efc = g.app.externalFilesController # Common arguments. if trace: g.trace(self.entire_file, root.h) # cursor_arg = self.get_cursor_arg() tab_arg = "-tab" if self.uses_tab else "" remote_arg = "--remote" + tab_arg + "-silent" args = [self.vim_exe, "--servername", "LEO", remote_arg] # No cursor arg. if self.entire_file: # vim-open-file assert root.isAnyAtFileNode(), root dir_ = g.setDefaultDirectory(c, root) fn = c.os_path_finalize_join(dir_, root.anyAtFileNodeName()) else: # vim-open-node ext = 'txt' fn = efc.create_temp_file(c, ext, c.p) c_arg = '%s %s' % (' '.join(args), fn) command = 'subprocess.Popen(%s,shell=True)' % c_arg if trace: g.trace(command) try: subprocess.Popen(c_arg, shell=True) except OSError: g.es_print(command) g.es_exception()
def compare_two_files(self, name1, name2): '''A helper function.''' f1 = f2 = None try: f1 = self.doOpen(name1) f2 = self.doOpen(name2) if self.outputFileName: self.openOutputFile() ok = self.outputFileName is None or self.outputFile ok = 1 if ok and ok != 0 else 0 if f1 and f2 and ok: # Don't compare if there is an error opening the output file. self.compare_open_files(f1, f2, name1, name2) except Exception: self.show("exception comparing files") g.es_exception() try: if f1: f1.close() if f2: f2.close() if self.outputFile: self.outputFile.close() self.outputFile = None except Exception: self.show("exception closing files") g.es_exception()
def scan(self, s, parent): '''Create an outline from a MindMap (.csv) file.''' # pylint: disable=no-member # pylint confuses this module with the stdlib json module c = self.c self.gnx_dict = {} try: d = json.loads(s) for d2 in d.get('nodes', []): gnx = d2.get('gnx') self.gnx_dict[gnx] = d2 top_d = d.get('top') if top_d: # Don't set parent.h or parent.gnx or parent.v.u. parent.b = top_d.get('b') or '' self.create_nodes(parent, top_d) c.redraw() return bool(top_d) except Exception: # Fix #1098 try: obj = json.loads(s) except Exception: g.error('Bad .json file: %s' % parent.h) g.es_exception() obj = s parent.b = g.objToString(obj) c.redraw() return True
def createNewMenu(self, menuName, parentName="top", before=None): try: parent = self.getMenu(parentName) # parent may be None. menu = self.getMenu(menuName) if menu: # Not an error. # g.error("menu already exists:", menuName) return None # Fix #528. else: menu = self.new_menu(parent, tearoff=0, label=menuName) self.setMenu(menuName, menu) label = self.getRealMenuName(menuName) amp_index = label.find("&") label = label.replace("&", "") if before: # Insert the menu before the "before" menu. index_label = self.getRealMenuName(before) amp_index = index_label.find("&") index_label = index_label.replace("&", "") index = parent.index(index_label) self.insert_cascade(parent, index=index, label=label, menu=menu, underline=amp_index) else: self.add_cascade(parent, label=label, menu=menu, underline=amp_index) return menu except Exception: g.es("exception creating", menuName, "menu") g.es_exception() return None
def open_with(self, c, d): ''' Called by c.openWith to handle items in the Open With... menu. 'd' a dict created from an @openwith settings node with these keys: 'args': the command-line arguments to be used to open the file. 'ext': the file extension. 'kind': the method used to open the file, such as subprocess.Popen. 'name': menu label (used only by the menu code). 'p': the nearest @<file> node, or None. 'shortcut': menu shortcut (used only by the menu code). ''' try: ext = d.get('ext') if not g.doHook('openwith1', c=c, p=c.p, v=c.p.v, d=d): root = d.get('p') if root: # Open the external file itself. directory = g.setDefaultDirectory(c, root) path = c.os_path_finalize_join(directory, root.anyAtFileNodeName()) self.open_file_in_external_editor(c, d, path) else: # Open a temp file containing just the node. p = c.p ext = self.compute_ext(c, p, ext) path = self.compute_temp_file_path(c, p, ext) if path: self.remove_temp_file(p, path) self.create_temp_file(c, ext, p) self.open_file_in_external_editor(c, d, path) g.doHook('openwith2', c=c, p=c.p, v=c.p.v, d=d) except Exception: g.es('unexpected exception in c.openWith') g.es_exception()
def setRealMenuNamesFromTable(self, table): try: for untrans, trans in table: self.setRealMenuName(untrans, trans) except Exception: g.es("exception in", "setRealMenuNamesFromTable") g.es_exception()
def create_temp_file(self, c, ext, p): ''' Create the file used by open-with if necessary. Add the corresponding ExternalFile instance to self.files ''' path = self.compute_temp_file_path(c, p, ext) exists = g.os_path_exists(path) # Compute encoding and s. d2 = c.scanAllDirectives(p) encoding = d2.get('encoding', None) if encoding is None: encoding = c.config.default_derived_file_encoding s = g.toEncodedString(p.b, encoding, reportErrors=True) # Write the file *only* if it doesn't exist. # No need to read the file: recomputing s above suffices. if not exists: try: with open(path, 'wb') as f: f.write(s) f.flush() except IOError: g.error('exception creating temp file: %s' % path) g.es_exception() return None # Add or update the external file entry. time = self.get_mtime(path) self.files = [z for z in self.files if z.path != path] self.files.append(ExternalFile(c, ext, p, path, time)) return path
def make_script_substitutions_in_headline(self, p): '''Make scripting substitutions in p.h.''' trace = False and not g.unitTesting c = self.c pattern = re.compile('^(.*)%s(.+)%s(.*)$' % ( re.escape(c.abbrev_subst_start), re.escape(c.abbrev_subst_end), )) changed = False if trace: g.trace(p.h) # Perform at most one scripting substition. m = pattern.match(p.h) if m: content = m.group(2) if trace: g.trace('MATCH:', m.group(1)) c.abbrev_subst_env['x'] = '' try: exec(content, c.abbrev_subst_env, c.abbrev_subst_env) x = c.abbrev_subst_env.get('x') if x: p.h = "%s%s%s" % (m.group(1), x, m.group(3)) changed = True elif trace: g.trace('ignoring empty result', p.h) except Exception: # Leave p.h alone. g.trace('scripting error in', p.h) g.es_exception() return changed
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 update_vs(self): ''' Evaluate @r <expr> nodes, puting the result in their body text. Output @vso nodes, based on file extension ''' c = self.c for p in c.all_unique_positions(): h = p.h.strip() if h.startswith('@r '): expr = h[3:].strip() try: result = eval(expr,self.d) except Exception: g.es_exception() g.es("Failed to render " + h) continue self.render_value(p,result) if h.startswith("@vso "): expr = h[5:].strip() bname, ext = os.path.splitext(expr) try: result = eval(bname,self.d) except Exception: g.es_exception() g.es("@vso failed: " + h) continue if ext.lower() == '.json': cnt = json.dumps(result, indent = 2) pth = os.path.join(c.getNodePath(p), expr) self.render_value(p, cnt) g.es("Writing @vso: " + pth) open(pth, "w").write(cnt) else: g.es_error("Unknown vso extension (should be .json, ...): " + ext)
def compare_files(self, name1, name2): if name1 == name2: self.show("File names are identical.\nPlease pick distinct files.") return f1 = f2 = None try: f1 = self.doOpen(name1) f2 = self.doOpen(name2) if self.outputFileName: self.openOutputFile() ok = self.outputFileName is None or self.outputFile ok = 1 if ok and ok != 0 else 0 if f1 and f2 and ok: # Don't compare if there is an error opening the output file. self.compare_open_files(f1, f2, name1, name2) except Exception: self.show("exception comparing files") g.es_exception() try: if f1: f1.close() if f2: f2.close() if self.outputFile: self.outputFile.close(); self.outputFile = None except Exception: self.show("exception closing files") g.es_exception()
def open_file(self, root): '''Open the the file in vim using c.openWith.''' c = self.c efc = g.app.externalFilesController # Common arguments. tab_arg = "-tab" if self.uses_tab else "" remote_arg = "--remote" + tab_arg + "-silent" args = [self.vim_exe, "--servername", "LEO", remote_arg] # No cursor arg. if self.entire_file: # vim-open-file args.append( '+0') # Go to first line of the file. This is an Ex command. assert root.isAnyAtFileNode(), root # Use os.path.normpath to give system separators. fn = os.path.normpath(g.fullPath(c, root)) # #1914. else: # vim-open-node args.append(self.get_cursor_arg()) # Set the cursor position to the current line in the node. ext = 'txt' fn = efc.create_temp_file(c, ext, c.p) c_arg = '%s %s' % (' '.join(args), fn) command = 'subprocess.Popen(%s,shell=True)' % c_arg try: subprocess.Popen(c_arg, shell=True) except OSError: g.es_print(command) g.es_exception()
def update(self, tag, keywords): '''Update the vr pane.''' verbose = False pc = self p = pc.c.p if pc.must_update(keywords): if trace and verbose: g.trace('===== updating', keywords) # Suppress updates until we change nodes. pc.node_changed = pc.gnx != p.v.gnx pc.gnx = p.v.gnx pc.length = len(p.b) # not s # Remove Leo directives. s = keywords.get('s') if 's' in keywords else p.b s = pc.remove_directives(s) # Dispatch based on the computed kind. kind = keywords.get('flags') if 'flags' in keywords else pc.get_kind(p) f = pc.dispatch_dict.get(kind) if f: if trace and verbose: g.trace(p.h, f.__name__) else: g.trace('no handler for kind: %s' % kind) f = pc.update_rst f(s, keywords) else: # Save the scroll position. w = pc.w if w.__class__ == QtWidgets.QTextBrowser: # 2011/07/30: The widget may no longer exist. try: sb = w.verticalScrollBar() pc.scrollbar_pos_dict[p.v] = sb.sliderPosition() except Exception: g.es_exception() pc.deactivate()
def eventFilter(self, obj, event): c, k = self.c, self.c.k # # Handle non-key events first. if not self.c.p: return False # Startup. Let Qt handle the key event if 'keys' in g.app.debug and isinstance(event, QtGui.QKeyEvent): self.traceKeys(obj, event) elif 'events' in g.app.debug: self.traceEvent(obj, event) self.traceWidget(event) if self.doNonKeyEvent(event, obj): return False # Let Qt handle the non-key event. # # Ignore incomplete key events. if self.shouldIgnoreKeyEvent(event, obj): return False # Let Qt handle the key event. # # Generate a g.KeyStroke for k.masterKeyHandler. try: binding, ch = self.toBinding(event) if not binding: return False # Not the correct event type. # # Pass the KeyStroke to masterKeyHandler. key_event = self.createKeyEvent(event, c, self.w, ch, binding) k.masterKeyHandler(key_event) c.outerUpdate() except Exception: g.es_exception() return True
def make_script_substitutions_in_headline(self, p): '''Make scripting substitutions in p.h.''' trace = False and not g.unitTesting c = self.c pattern = re.compile('^(.*)%s(.+)%s(.*)$' % ( re.escape(c.abbrev_subst_start), re.escape(c.abbrev_subst_end), )) changed = False if trace: g.trace('===== p', p.h) # Perform at most one scripting substition. m = pattern.match(p.h) if m: content = m.group(2) if trace: g.trace('MATCH:', m.group(1)) c.abbrev_subst_env['x'] = '' try: exec(content, c.abbrev_subst_env, c.abbrev_subst_env) x = c.abbrev_subst_env.get('x') if x: p.h = "%s%s%s" % (m.group(1), x, m.group(3)) changed = True elif trace: g.trace('ignoring empty result', p.h) except Exception: # Leave p.h alone. g.trace('scripting error in', p.h) g.es_exception() return changed
def callTagHandler(self, bunch, tag, keywords): '''Call the event handler.''' trace = False and not g.unitTesting traceIdle = True handler, moduleName = bunch.fn, bunch.moduleName if trace and (traceIdle or tag != 'idle'): c = keywords.get('c') name = moduleName tag2 = 'leo.plugins.' if name.startswith(tag2): name = name[len(tag2):] g.trace('c: %s %23s : %s . %s' % (c and c.shortFileName() or '<no c>', tag, handler.__name__, name)) # Make sure the new commander exists. for key in ('c', 'new_c'): c = keywords.get(key) if c: # Make sure c exists and has a frame. if not c.exists or not hasattr(c, 'frame'): # g.pr('skipping tag %s: c does not exist or does not have a frame.' % tag) return None # Calls to registerHandler from inside the handler belong to moduleName. self.loadingModuleNameStack.append(moduleName) try: result = handler(tag, keywords) except Exception: g.es("hook failed: %s, %s, %s" % (tag, handler, moduleName)) g.es_exception() result = None self.loadingModuleNameStack.pop() return result
def openOutputFile(self): if self.outputFileName == None: return theDir, name = g.os_path_split(self.outputFileName) if len(theDir) == 0: self.show("empty output directory") return if len(name) == 0: self.show("empty output file name") return if not g.os_path_exists(theDir): self.show("output directory not found: " + theDir) else: try: if self.appendOutput: self.show("appending to " + self.outputFileName) self.outputFile = open(self.outputFileName, "ab") else: self.show("writing to " + self.outputFileName) self.outputFile = open(self.outputFileName, "wb") except: self.outputFile = None self.show("exception opening output file") g.es_exception()
def init_env(self): ''' Init c.abbrev_subst_env by executing the contents of the @data abbreviations-subst-env node. ''' c = self.c at = c.atFileCommands if c.abbrev_place_start and self.enabled: aList = self.subst_env script = [] for z in aList: # Compatibility with original design. if z.startswith('\\:'): script.append(z[2:]) else: script.append(z) script = ''.join(script) # Allow Leo directives in @data abbreviations-subst-env trees. import leo.core.leoNodes as leoNodes v = leoNodes.VNode(context=c) root = leoNodes.Position(v) # Similar to g.getScript. script = at.writeFromString( root=root, s=script, forcePythonSentinels=True, useSentinels=False) script = script.replace("\r\n", "\n") try: exec(script, c.abbrev_subst_env, c.abbrev_subst_env) except Exception: g.es('Error exec\'ing @data abbreviations-subst-env') g.es_exception() else: c.abbrev_subst_start = False
def getIDFromFile(self): '''Attempt to set g.app.leoID from leoID.txt.''' g = self.g trace = False and not g.app.silentMode tag = ".leoID.txt" for theDir in (g.app.homeDir, g.app.globalConfigDir, g.app.loadDir): if not theDir: continue # do *not* use the current directory! fn = g.os_path_join(theDir, tag) try: with open(fn, 'r') as f: s = f.readline().strip() if not s: continue g.app.leoID = s if trace: g.es('leoID=%r (in %s)' % (s, theDir), color='red') else: g.es('leoID=%r' % (s), color='red') except IOError: g.app.leoID = None except Exception: g.app.leoID = None g.error('unexpected exception in app.setLeoID') g.es_exception()
def callTagHandler (self,bunch,tag,keywords): '''Call the event handler.''' trace = False and not g.unitTesting traceIdle = True handler,moduleName = bunch.fn,bunch.moduleName if trace and (traceIdle or tag != 'idle'): c = keywords.get('c') name = moduleName ; tag2 = 'leo.plugins.' if name.startswith(tag2): name = name[len(tag2):] g.trace('c: %s %23s : %s . %s' % ( c and c.shortFileName() or '<no c>', tag,handler.__name__,name)) # Make sure the new commander exists. for key in ('c','new_c'): c = keywords.get(key) if c: # Make sure c exists and has a frame. if not c.exists or not hasattr(c,'frame'): # g.pr('skipping tag %s: c does not exist or does not have a frame.' % tag) return None # Calls to registerHandler from inside the handler belong to moduleName. self.loadingModuleNameStack.append(moduleName) try: result = handler(tag,keywords) except Exception: g.es("hook failed: %s, %s, %s" % (tag, handler, moduleName)) g.es_exception() result = None self.loadingModuleNameStack.pop() return result
def update(self,tag,keywords): '''Update the vr pane.''' pc = self c,p = pc.c,pc.c.p if pc.must_update(keywords): if trace: g.trace('===== updating',keywords) # Suppress updates until we change nodes. pc.node_changed = pc.gnx != p.v.gnx pc.gnx = p.v.gnx pc.length = len(p.b) # not s # Remove Leo directives. s = keywords.get('s') if 's' in keywords else p.b s = pc.remove_directives(s) # Dispatch based on the computed kind. kind = keywords.get('flags') if 'flags' in keywords else pc.get_kind(p) f = pc.dispatch_dict.get(kind) if f: if trace: g.trace(f.__name__) else: g.trace('no handler for kind: %s' % kind) f = pc.update_rst f(s,keywords) else: # Save the scroll position. w = pc.w if w.__class__ == pc.text_class: # 2011/07/30: The widge may no longer exist. try: sb = w.verticalScrollBar() except Exception: g.es_exception() pc.deactivate() if sb: pc.scrollbar_pos_dict[p.v] = sb.sliderPosition()
def adjustDefStart(self, s, i): '''A hook to allow the Python importer to adjust the start of a class or function to include decorators. ''' # Invariant: i does not change. # Invariant: start is the present return value. try: assert s[i] != '\n' start = j = g.find_line_start(s, i) if i > 0 else 0 # g.trace('entry',j,i,repr(s[j:i+10])) assert j == 0 or s[j - 1] == '\n' while j > 0: progress = j j1 = j = g.find_line_start(s, j - 2) # g.trace('line',repr(s[j:progress])) j = g.skip_ws(s, j) if not g.match(s, j, '@'): break k = g.skip_id(s, j + 1) word = s[j: k] # Leo directives halt the scan. if word and word in g.globalDirectiveList: break # A decorator. start = j = j1 assert j < progress # g.trace('**returns %s, %s' % (repr(s[start:i]),repr(s[i:i+20]))) return start except AssertionError: g.es_exception() return i
def open_file(self, root): '''Open the the file in vim using c.openWith.''' trace = False and not g.unitTesting c = self.c # Common arguments. if trace: g.trace(self.entire_file, root.h) cursor_arg = self.get_cursor_arg() tab_arg = "-tab" if self.uses_tab else "" remote_arg = "--remote" + tab_arg + "-silent" if self.entire_file: # vim-open-file. assert root.isAnyAtFileNode(), root args = [self.vim_exe, "--servername", "LEO", remote_arg] # No cursor arg. dir_ = g.setDefaultDirectory(c, root) fn = c.os_path_finalize_join(dir_, root.anyAtFileNodeName()) c_arg = '%s %s' % (' '.join(args), fn) command = 'subprocess.Popen(%s,shell=True)' % c_arg if trace: g.trace(command) try: subprocess.Popen(c_arg, shell=True) except OSError: g.es_print(command) g.es_exception() else: # vim-open-node root.v._vim_old_body = root.v.b # Not used in existing code, but it may be used elsewhere. args = [self.vim_exe, "--servername", "LEO", remote_arg, cursor_arg] if trace: g.trace('c.openWith(%s)' % args) d = {'args': args, 'ext': None, 'kind': 'subprocess.Popen', 'p': root.copy(), } c.openWith(d=d)
def create_temp_file(self, c, ext, p): ''' Create the temp file used by open-with if necessary. Add the corresponding ExternalFile instance to self.files ''' trace = False and not g.unitTesting if trace: g.trace(len(p.b), p.h) path = self.temp_file_path(c, p, ext) exists = g.os_path_exists(path) if trace: kind = 'recreating:' if exists else 'creating: ' g.trace(kind, path) # Compute encoding and s. d2 = c.scanAllDirectives(p) encoding = d2.get('encoding', None) if encoding is None: encoding = c.config.default_derived_file_encoding s = g.toEncodedString(p.b, encoding, reportErrors=True) # Write the file *only* if it doesn't exist. # No need to read the file: recomputing s above suffices. if not exists: try: f = open(path, 'wb') f.write(s) f.flush() f.close() except IOError: g.error('exception creating temp file: %s' % path) g.es_exception() return None # Add or update the external file entry. time = self.get_mtime(path) self.files = [z for z in self.files if z.path != path] self.files.append(ExternalFile(c, ext, p, path, time)) return path
def openOutputFile (self): if self.outputFileName == None: return theDir,name = g.os_path_split(self.outputFileName) if len(theDir) == 0: self.show("empty output directory") return if len(name) == 0: self.show("empty output file name") return if not g.os_path_exists(theDir): self.show("output directory not found: " + theDir) else: try: if self.appendOutput: self.show("appending to " + self.outputFileName) self.outputFile = open(self.outputFileName,"ab") else: self.show("writing to " + self.outputFileName) self.outputFile = open(self.outputFileName,"wb") except: self.outputFile = None self.show("exception opening output file") g.es_exception()
def applyNodeAction(pScript, pClicked, c): script = g.getScript(c, pScript) if script: working_directory = os.getcwd() file_directory = c.frame.openDirectory os.chdir(file_directory) script += '\n' #Redirect output if c.config.redirect_execute_script_output_to_log_pane: g.redirectStdout() # Redirect stdout g.redirectStderr() # Redirect stderr try: namespace = { 'c':c, 'g':g, 'pClicked': pClicked, 'pScript' : pScript, 'shellScriptInWindowNA': shellScriptInWindowNA } # exec script in namespace exec(script,namespace) #Unredirect output if c.config.redirect_execute_script_output_to_log_pane: g.restoreStderr() g.restoreStdout() except: #Unredirect output if c.config.redirect_execute_script_output_to_log_pane: g.restoreStderr() g.restoreStdout() g.es("exception in NodeAction plugin") g.es_exception(full=False,c=c) os.chdir(working_directory)
def eventFilter(self, obj, event): c, k = self.c, self.c.k # # Handle non-key events first. if not self.c.p: return False # Startup. Let Qt handle the key event if 'events' in g.app.debug: self.traceEvent(obj, event) self.traceWidget(event) if self.doNonKeyEvent(event, obj): return False # Let Qt handle the non-key event. # # Ignore incomplete key events. if self.shouldIgnoreKeyEvent(event, obj): return False # Let Qt handle the key event. # # Generate a g.KeyStroke for k.masterKeyHandler. try: binding, ch = self.toBinding(event) if not binding: return False # Allow Qt to handle the key event. # # Pass the KeyStroke to masterKeyHandler. key_event = self.createKeyEvent(event, c, self.w, ch, binding) k.masterKeyHandler(key_event) c.outerUpdate() except Exception: g.es_exception() return True
def command_helper(self, event, kind, preview, verbose): def predicate(p): return self.filename(p) # Find all roots. t1 = time.time() c = self.c self.kind = kind p = event.p if event and hasattr(event, 'p') else c.p roots = g.findRootsWithPredicate(c, p, predicate=predicate) if not roots: g.warning('No @adoc nodes in', p.h) return [] # Write each root to a file. i_paths = [] for p in roots: try: i_path = self.filename(p) # #1398. i_path = c.expand_path_expression(i_path) i_path = g.os_path_finalize(i_path) with open(i_path, 'w', encoding='utf-8', errors='replace') as self.output_file: self.write_root(p) i_paths.append(i_path) except IOError: g.es_print(f"Can not open {i_path!r}") except Exception: g.es_print(f"Unexpected exception opening {i_path!r}") g.es_exception() # Convert each file to html. o_paths = [] for i_path in i_paths: o_path = self.compute_opath(i_path) o_paths.append(o_path) if kind == 'adoc': self.run_asciidoctor(i_path, o_path) elif kind == 'pandoc': self.run_pandoc(i_path, o_path) elif kind == 'sphinx': self.run_sphinx(i_path, o_path) else: g.trace('BAD KIND') return None if kind != 'sphinx': print(f"{kind}: wrote {o_path}") if preview: if kind == 'sphinx': g.es_print('preview not available for sphinx') else: # open .html files in the default browser. g.execute_shell_commands(o_paths) t2 = time.time() if verbose: n = len(i_paths) g.es_print(f"{kind}: wrote {n} file{g.plural(n)} " f"in {(t2-t1):4.2f} sec.") return i_paths
def __setitem__(self, key, value): """ db['key'] = 5 """ try: data = self.dumper(value) self.conn.execute('''replace into cachevalues(key, data) values(?,?);''', (key, data)) except sqlite3.OperationalError as e: g.es_exception(e)
def sync_transformations(event): c = event.get('c') gnxDict = c.fileCommands.gnxDict trscripts = {} trtargets = {} #@+others #@+node:vitalije.20180805121201.1: *3* collect_data def collect_data(): p = c.rootPosition() seen = set() while p: v = p.v if v.gnx in seen: p.moveToNodeAfterTree() continue seen.add(v.gnx) h = v.h if h.startswith('@transformer '): name = h.partition(' ')[2].strip() trscripts[name] = g.getScript(c, p.copy(), useSentinels=False, forcePythonSentinels=True) p.moveToNodeAfterTree() elif h.startswith('@transform-node '): name = h.partition(' ')[2].strip() name, sep, rest = name.partition('(') if not sep: g.warning('wrong syntax expected "("', nodeLink=p) p.moveToThreadNext() continue srcgnx, sep, rest = rest.partition(')') if not sep: g.warning('wrong syntax expected ")"', nodeLink=p) p.moveToThreadNext() continue srcgnx = srcgnx.strip() if not srcgnx in c.fileCommands.gnxDict: g.warning('unknown gnx', srcgnx, nodeLink=p) p.moveToThreadNext() continue trtargets[v.gnx] = (name, srcgnx) p.moveToThreadNext() else: p.moveToThreadNext() #@-others collect_data() count = 0 for dst, args in trtargets.items(): name, src = args code = trscripts.get(name, 'out.write("not found transformer code")') out = io.StringIO() try: exec(code, dict(v=gnxDict[src], out=out, g=g, c=c)) gnxDict[dst].b = out.getvalue() count += 1 except Exception: g.es_exception(True, c) if count: g.es('%d node(s) transformed'%count)
def sync_transformations(event): c = event.get('c') gnxDict = c.fileCommands.gnxDict trscripts = {} trtargets = {} #@+others #@+node:vitalije.20180805121201.1: *3* collect_data def collect_data(): p = c.rootPosition() seen = set() while p: v = p.v if v.gnx in seen: p.moveToNodeAfterTree() continue seen.add(v.gnx) h = v.h if h.startswith('@transformer '): name = h.partition(' ')[2].strip() trscripts[name] = g.getScript(c, p.copy(), useSentinels=False, forcePythonSentinels=True) p.moveToNodeAfterTree() elif h.startswith('@transform-node '): name = h.partition(' ')[2].strip() name, sep, rest = name.partition('(') if not sep: g.warning('wrong syntax expected "("', nodeLink=p) p.moveToThreadNext() continue srcgnx, sep, rest = rest.partition(')') if not sep: g.warning('wrong syntax expected ")"', nodeLink=p) p.moveToThreadNext() continue srcgnx = srcgnx.strip() if not srcgnx in c.fileCommands.gnxDict: g.warning('unknown gnx', srcgnx, nodeLink=p) p.moveToThreadNext() continue trtargets[v.gnx] = (name, srcgnx) p.moveToThreadNext() else: p.moveToThreadNext() #@-others collect_data() count = 0 for dst, args in trtargets.items(): name, src = args code = trscripts.get(name, 'out.write("not found transformer code")') out = g.fileLikeObject() try: exec(code, dict(v=gnxDict[src], out=out, g=g, c=c)) gnxDict[dst].b = out.get() count += 1 except Exception: g.es_exception(True, c) if count: g.es('%d node(s) transformed'%count)
def unpickle(self, s): """Unhexlify and unpickle string s into p.""" try: bin = binascii.unhexlify(g.toEncodedString(s)) # Throws TypeError if s is not a hex string. return pickle.loads(bin) except Exception: g.es_exception() return None
def unpickle (self,s): '''Unhexlify and unpickle string s into p.''' try: bin = binascii.unhexlify(g.toEncodedString(s)) # Throws TypeError if s is not a hex string. return pickle.loads(bin) except Exception: g.es_exception() return None