def show_binds(self): """ Show keybindings """ self.fire_event("show_binds") _data = self.xyz.km.get_binds() _entries = [] _divattr = self.xyz.skin.attr(uilib.XYZListBox.resolution, u"border") _entries.append(lowui.Text(u"%-10s %-20s %s" % (_(u"Context"), _(u"Bind"), _(u"Method / Description")))) _entries.append(uilib.Separator(div_attr=_divattr)) for _context in sorted(_data.keys()): for _bind in sorted(_data[_context].keys(), cmp=lambda x, y: cmp(bstring(x), bstring(y))): if _data[_context][_bind] is None: continue _entries.append(lowui.Text(u"%-10s %-20s %s" % (_context, _bind, _data[_context][_bind].ns))) _walker = lowui.SimpleListWalker(_entries) _dim = tuple([x - 2 for x in self.xyz.screen.get_cols_rows()]) uilib.XYZListBox(self.xyz, self.xyz.top, _walker, _(u"Keybindings"), _dim).show()
def _gid(self, gid): _name = util.get_group(gid) if _name is not None: return "%s (%s)" % (bstring(gid), _name) else: return bstring(gid)
def _uid(self, uid): _name = util.get_user(uid) if _name is not None: return "%s (%s)" % (bstring(uid), _name) else: return bstring(uid)
def complete(self, buf): """ Take current buffer and return list-generator of all matched entries in current domain. @param buf: Current buffer @return: list-generator """ buf = bstring(buf) if os.path.isdir(buf): _dir = buf _obj = "" # Treat as current dir elif os.path.sep not in buf: _dir = "." _obj = buf else: _dir = os.path.dirname(buf) _obj = os.path.basename(buf) _, dirs, files = os.walk(_dir).next() return itertools.ifilter(lambda x: x.startswith(_obj), dirs + files)
def show_box(self, use_wrap=True): """ Show test_box dialog @param use_wrap: Whether to use input wrapper which honours learned keys """ _msg = _(u"Press any key. Escape twice to quit.") _escape = 0 _escape_key = uilib.Shortcut(sc=[self._keys.ESCAPE]) while True: shortcut = InputBox(self.xyz, self.xyz.top, bstring(_msg), _(u"Input test")).show(use_wrap=use_wrap) if shortcut == _escape_key: _escape += 1 if _escape == 2: return else: _escape = 0 method = self.xyz.km.get_method_by_key(shortcut) _msg = u"Shortcut: '%s'. Raw: '%s'" % ( (u" ".join([ustring(x) for x in shortcut.sc]), u" ".join([ustring(x) for x in shortcut.raw]))) if method is not None: _msg = u"%s\n[%s]" % (_msg, method.ns)
def execute(self, cmd, wait=None): """ Execute command in shell """ cmd = bstring(cmd) self.fire_event("execute", cmd) def _exec(): pid = os.fork() # Child - Exec passed cmd if pid == 0: os.execvp(self.shell[0], self.shell + [cmd]) # WTF? sys.exit() # Parent else: while True: try: self.status = os.waitpid(pid, 0) except KeyboardInterrupt: pass except OSError, e: if e.errno != errno.EINTR: break return self.status
def complete(self, buf): """ Take current buffer and return list-generator of all matched entries in current domain. @param buf: Current buffer @return: list-generator """ return itertools.ifilter(lambda x: x.startswith(bstring(buf)), self._data)
def _press_key(self, msg, key): """ Print prompt and wait for the key to be pressed """ sys.stdout.write(bstring(msg)) sys.stdout.flush() while True: try: m = os.read(sys.stdin.fileno(), 1024) if key in m: break except OSError, e: if e.errno != errno.EINTR: break
def show(self, dim=None, exit_keys=None): """ Show window. Update contents as user types """ exit_keys = exit_keys or [] if dim is None: dim = self.xyz.screen.get_cols_rows() _buf = u"" _title = self.title while True: self.xyz.screen.draw_screen(dim, self.render(dim, True)) _i = self.xyz.input.get() if self.xyz.input.WIN_RESIZE in _i: dim = self.xyz.screen.get_cols_rows() continue update = False if _i: for _k in _i: if _k == self._keys.ESC: return elif _k == self._keys.BACKSPACE: _buf = _buf[:-1] update = True elif _k == self._keys.ENTER: entry, _ = self.listbox.get_focus() return entry.text elif len(ustring(_k)) == 1: _buf += _k update = True else: self._listbox.keypress(dim, _k) if update: _b = bstring(_buf) self.set_title(u"%s: %s" % (_title, _buf)) self.listbox.body.contents = [x for x in self._extra if _b in x._text]
def _exec_engine(self, cmd, cmdf, wait=None): """ Execute command engine """ self.xyz.screen.clear() stdout = sys.stdout self.xyz.screen.stop() _current_term = None # Restore original terminal settings if self.xyz.term is not None: _current_term = core.utils.term_settings()[-1] core.utils.restore_term(self.xyz.term) # Clear the screen #TODO: make it more portable! stdout.write("\x1b[H\x1b[2J") stdout.write("%s%s\n" % (bstring( self.xyz.conf[u"plugins"][":sys:cmd"][u"prompt"]), cmd)) stdout.flush() def _sigwinch(_a, _b): self.xyz.screen.resized = True signal.signal(signal.SIGWINCH, _sigwinch) status = cmdf() if _current_term is not None: core.utils.restore_term(_current_term) if wait == True or (wait != False and self.conf["wait"]): self._press_key(_(u"Press ENTER to continue..."), "\n") self.xyz.screen.start() return status
def complete(self, buf): """ Take current buffer and return list-generator of all matched entries in current domain. @param buf: Current buffer @return: list-generator """ cmd = split_cmd(bstring(buf)) _len = len(cmd) if len(cmd) == 1: obj = "" else: obj = cmd[-1] _, _, files = os.walk(self.INITD_DIR).next() return itertools.ifilter(lambda x: x.startswith(obj), files)
def complete(self, buf, domains=None): """ Take current buffer and return list of list-generator each entry for each domain. @param buf: Current buffer @param domains: List of domains to search in, if None search in all available domains. @return: List of list-generator each entry for each domain """ buf = bstring(buf) result = [] if domains is None: domains = self._domains.keys() for d in domains: result.append(self._domains[d].complete(buf)) return result
def mkdir(self): """ Create new directory dialog """ self._load_panel() _box = uilib.InputBox(self.xyz, self.xyz.top, _(u"New directory name"), title=_(u"Create directory")) _dir = _box.show() if not _dir: return else: _dir = bstring(_dir) try: self._panel.get_current().mkdir(_dir) except Exception, e: xyzlog.error(_(u"Unable to create directory: %s") % unicode(e))
def smart_complete(self, cmd): """ Try to guess what completion domain can be used based on provided buffer and defined behaviour. @param cmd: Current buffer @return: List of list-generator each entry for each domain """ if not cmd: return data = None pat_used = False buf = bstring(split_cmd(cmd)[-1]) # First check the behaviour patterns for (pattern, domain) in self.conf["behaviour"]: if pattern.search(cmd) is not None: pat_used = True data = self.dialog(cmd, [domain]) break # Else default fallback behaviour applied if pat_used == False: # Treat as path if buf.startswith(os.path.sep) or buf.startswith("./") or \ buf.startswith("../"): data = self.dialog(buf, ["fs"]) else: # Treat as command in $PATH data = self.dialog(buf, ["binpath"]) if data is not None: data = intersect(buf, data) self.xyz.pm.from_load(":sys:cmd", "append")(data)
def __init__(self, xyz, srctxt, dst, caption): self.xyz = xyz self._attr = lambda name: self.xyz.skin.attr(self.resolution, name) self._keys = uilib.Keys() srclabel = lowui.Text(bstring(_(u"Source:"))) srctxt = lowui.Text(bstring(srctxt)) dstlabel = lowui.Text(bstring(_(u"Destination:"))) self.dstw = lowui.AttrWrap(lowui.Edit(edit_text=ustring(dst), wrap='clip'), self._attr("input")) self.save_attrw = lowui.CheckBox(bstring(_(u"Save attributes")), state=True) self.follow_linksw = lowui.CheckBox(bstring(_(u"Follow links"))) self.buttonsw = lowui.Columns([self.save_attrw, self.follow_linksw]) spacer = lowui.Text(" ") msg = lowui.Text( bstring(_(u"TAB to cycle. ENTER to submit. ESCAPE to cancel")), align=uilib.align.CENTER) w = [ srclabel, srctxt, spacer, dstlabel, self.dstw, spacer, self.buttonsw, uilib.Separator(), msg ] self.widgets = lowui.Pile(w) box = lowui.AttrWrap(lowui.Filler(self.widgets), self._attr("box")) self.widget = uilib.Border(box, caption, self._attr("title"), self._attr("border")) super(CopyBox, self).__init__(self.widget)
def _write(self, msg): """ Write text to output """ self.output.extend([lowui.Text(x) for x in bstring(msg).split("\n")])
def show(self): def _setup(dim): width = int((dim[0] / 100.0) * 80) height = int((dim[1] / 100.0) * 40) mount = lowui.AttrWrap(lowui.Filler(lowui.Text(u"")), self._attr(u"mount")) mount = lowui.Overlay(mount, self.xyz.top, uilib.align.CENTER, width, uilib.align.MIDDLE, height) return lowui.Overlay(self.widget, mount, uilib.align.CENTER, width - 2, uilib.align.MIDDLE, height - 2) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def _focus_button(b): self.widgets.set_focus(self.buttonsw) self.buttonsw.set_focus(b) return b #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def _focus_edit(): self.widgets.set_focus(self.dstw) return self.dstw #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ focus_data = {1: lambda: _focus_edit(), 2: lambda: _focus_button(self.save_attrw), 3: lambda: _focus_button(self.follow_linksw) } focus = 1 focusw = self.dstw dim = self.xyz.screen.get_cols_rows() box = _setup(dim) result = None while True: self.xyz.screen.draw_screen(dim, box.render(dim, True)) _input = self.xyz.input.get() if self.xyz.input.WIN_RESIZE in _input: dim = self.xyz.screen.get_cols_rows() box = _setup(dim) continue if self._keys.TAB in _input: if focus >= len(focus_data): focus = 1 else: focus +=1 focusw = focus_data[focus]() elif self._keys.ESCAPE in _input: break elif self._keys.ENTER in _input: result = { 'dst': bstring(self.dstw.get_edit_text()), 'save_attributes': self.save_attrw.get_state(), 'follow_links': self.follow_linksw.get_state() } break else: for k in _input: focusw.keypress((dim[0],), k) return result
def _info(self): """ Show plugin detailed info """ def _add_info(): if _plugin.AUTHOR is not None: _data.append(lowui.Text(_(u"Author: %s") % _plugin.AUTHOR)) if _plugin.VERSION is not None: _data.append(lowui.Text(_(u"Version: %s") % _plugin.VERSION)) if _plugin.MIN_XYZ_VERSION is not None: _data.append(lowui.Text(_(u"Minimal compatible version: %s") % _plugin.MIN_XYZ_VERSION)) if _plugin.HOMEPAGE is not None: _data.append(lowui.Text(_(u"Homepage: %s") % _plugin.HOMEPAGE)) _data.append(_div) if _plugin.FULL_DESCRIPTION is not None: _data.append(lowui.Text(_plugin.FULL_DESCRIPTION)) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def make_args(func): _args, _varargs, _varkw, _def = inspect.getargspec(func) # We will be inspecting only methods, so always skip self if len(_args) == 1: return u"" _args = _args[1:] _tmp = [] # No defaults if _def is None: _tmp = _args else: _delta = len(_args) - len(_def) if _delta > 0: _tmp.extend(_args[:_delta]) _args = _args[_delta:] for _a, _d in zip(_args, _def): _tmp.append(u"=".join((ustring(_a), ustring(_d)))) return u",".join(_tmp) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def _add_public_data(): if _plugin.public_data: _data.append(uilib.Separator(_(u"Public data"), title_attr=_titleattr, div_attr=_divattr)) _dlen = len(_plugin.public_data) _di = 0 for k, v in _plugin.public_data.iteritems(): _data.append(lowui.Text(u"%s: %s" % (k, type(v)))) _di += 1 if _di < _dlen: _data.append(_div) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def _add_public_methods(): _data.append(uilib.Separator(_(u"Public methods"), title_attr=_titleattr, div_attr=_divattr)) _bind_data = self.xyz.km.get_binds() _len = len(_plugin.public) _i = 0 for k in sorted(_plugin.public.keys()): v = _plugin.public[k] if v.__doc__ is not None: _doc = v.__doc__.rstrip() else: _doc = v.__doc__ _cur_bind = _(u"N/A") # Try to find current binding for the method for context in _bind_data: for bind in _bind_data[context]: if _bind_data[context][bind] is v: _cur_bind = bind _data.append(lowui.Text(u"%s(%s) [%s]: %s" % (k, make_args(v), _cur_bind, _doc))) _i += 1 if _i < _len: _data.append(_div) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ _w = self._walker.get_focus()[0] _plugin = _w.plugin self.fire_event("info", _plugin) _divattr = self.xyz.skin.attr(uilib.XYZListBox.resolution, u"border") _titleattr = self.xyz.skin.attr(uilib.XYZListBox.resolution, u"title") _div = lowui.Text("") _data = [] _add_info() if _plugin.DOC is not None: _data.append(uilib.Separator(_(u"Plugin doc"), title_attr=_titleattr, div_attr=_divattr)) _data.append(lowui.Text(_plugin.DOC)) if isinstance(_plugin.EVENTS, list): _data.append(uilib.Separator(_(u"Plugin events"), title_attr=_titleattr, div_attr=_divattr)) for event, desc in _plugin.EVENTS: _data.append(lowui.Text("%s -- %s" % (bstring(_plugin.event_name(event)), bstring(desc)))) _add_public_data() _add_public_methods() _method_walker = lowui.SimpleListWalker(_data) _dim = tuple([x - 2 for x in self.xyz.screen.get_cols_rows()]) uilib.XYZListBox(self.xyz, self.xyz.top, _method_walker, _(u"Plugin info %s") % _plugin.ns, _dim).show()
def copy(self, move=False): """ Copy objects dialog """ self._load_panel() objs = self._panel.get_active() if not objs: return if len(objs) == 1: srctxt = ustring(objs[0].full_path) else: srctxt = _(u"%d objects") % len(objs) srctxt = bstring(srctxt) if move: _m = _(u"Move") msg = _(u"Moving object: %s") caption = _(u"Moving") unable_msg = _(u"Unable to move object: %s") unable_caption = _(u"Move error") else: _m = _(u"Copy") msg = _(u"Copying object: %s") caption = _(u"Copying") unable_msg = _(u"Unable to copy object: %s") unable_caption = _(u"Copy error") msg += _(u"\nESCAPE to abort") data = CopyBox(self.xyz, srctxt, self._panel.cwd(active=False), bstring(_m)).show() if data is None: return stopped = threading.Event() cancel = threading.Event() free = threading.Event() free.set() def existcb(vfsobj): free.clear() buttons = [ (_(u"Yes"), "override"), (_(u"All"), "override all"), (_(u"Skip"), "skip"), (_(u"Skip all"), "skip all"), (_(u"Abort"), "abort"), ] try: name = ustring(vfsobj.name) _rec = uilib.ButtonBox( self.xyz, self.xyz.top, _(u"Object %s already exists. Really override?") % name, buttons, title=_(u"Override %s") % name).show() uilib.MessageBox(self.xyz, self.xyz.top, caption, caption).show(wait=False) free.set() return _rec or 'abort' except Exception: free.set() #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def errorcb(vfsobj, errstr): free.clear() buttons = [ (_(u"Skip"), "skip"), (_(u"Skip all"), "skip all"), (_(u"Abort"), "abort"), ] try: _rec = uilib.ButtonBox( self.xyz, self.xyz.top, _(u"An error occured %s: %s") % ( ustring(vfsobj.full_path), ustring(errstr)), buttons, title=_(u"Copy error")).show() uilib.MessageBox(self.xyz, self.xyz.top, caption, caption).show(wait=False) free.set() return _rec or 'abort' except Exception: free.set() #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ args = { "existcb": existcb, "errorcb": errorcb, "save_attrs": data["save_attributes"], "follow_links": data["follow_links"], "cancel": cancel } runner_error = [] def frun(o, err): stopped.clear() try: if move: attr = "move" else: attr = "copy" getattr(o, attr)(data["dst"], **args) except StopIteration, e: pass except Exception, e: err.append(unicode(e))
def __init__(self, xyz, path, full_path, ext_path, driver, parent, enc=None, **kwargs): self.xyz = xyz self.enc = enc or xyzenc # Internal VFS path self.path = bstring(path, self.enc) # Full VFS path self.full_path = bstring(full_path, self.enc) # External VFS path self.ext_path = bstring(ext_path, self.enc) self.parent = parent self.driver = driver self.kwargs = kwargs self.fileobj = None # File name self.name = os.path.basename(self.path) # File type self.ftype = None # Access time self.atime = None # Modified time self.mtime = None # Changed time self.ctime = None # Size in bytes self.size = None # Owner UID self.uid = None # Group self.gid = None # Mode self.mode = None # Inode self.inode = None # Visual file type self.vtype = None # Visual file representation self.visual = None # File info self.info = None # Any type-specific data self.data = None # List of significant attributes self.attributes = () # Run local constructor self._prepare() self.__ni_msg = _(u"Feature not implemented")
try: return _parser.parse(_file) except ParseError, e: xyzlog.error(_(u"Error parsing bookmarks file: %s") % unicode(e)) _file.close() return None #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def _save_data(self, data): """ Save data to bookmarks file data is a mapping: {name: path} """ try: _file = self._ud.openfile(self._bmfile, "w", self._bmsubdir) except XYZRuntimeError, e: xyzlog.info("Unable to open bookmarks file: %s" % unicode(e)) return None for _name, _path in data.iteritems(): _file.write('"%s": "%s"\n' % (bstring(_name), bstring(_path))) _file.close() return True