⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filediff.py

📁 LINUX下的文件比较工具
💻 PY
📖 第 1 页 / 共 4 页
字号:
        x = self.keylookup.get(event.keyval, 0)        if self.keymask & ~x != self.keymask:            self.keymask &= ~x            for l in self.linkmap[:self.num_panes-1]:                a = l.get_allocation()                w = self.pixbuf_copy0.get_width()                l.queue_draw_area(0,      0, w, a[3])                l.queue_draw_area(a[2]-w, 0, w, a[3])    def is_modified(self):        state = [b.modified for b in self.bufferdata]        return 1 in state    def _get_filename(self, i):        return self.bufferdata[i].filename or "<unnamed>"    def on_delete_event(self, appquit=0):        modified = [b.modified for b in self.bufferdata]        if 1 in modified:            dialog = gnomeglade.Component( paths.share_dir("glade2/filediff.glade"), "closedialog")            dialog.widget.set_transient_for(self.widget.get_toplevel())            buttons = []            for i in range(self.num_panes):                b = gtk.CheckButton( self._get_filename(i) )                b.set_use_underline(False)                buttons.append(b)                dialog.box.pack_start(b, 1, 1)                if not modified[i]:                    b.set_sensitive(0)                else:                    b.set_active(1)            dialog.widget.show_all()            if not appquit:                dialog.button_quit.hide()            response = dialog.widget.run()            try_save = [ b.get_active() for b in buttons]            dialog.widget.destroy()            if response==gtk.RESPONSE_OK:                for i in range(self.num_panes):                    if try_save[i]:                        if self.save_file(i) != melddoc.RESULT_OK:                            return gtk.RESPONSE_CANCEL            elif response==gtk.RESPONSE_CLOSE:                return gtk.RESPONSE_CLOSE            else:                return gtk.RESPONSE_CANCEL        return gtk.RESPONSE_OK        #        # text buffer undo/redo        #    def on_text_begin_user_action(self, *buffer):        self.undosequence.begin_group()    def on_text_end_user_action(self, *buffer):        self.undosequence.end_group()    def on_text_insert_text(self, buffer, it, text, textlen):        if not self.undosequence_busy:            self.undosequence.begin_group()            pane = self.textview.index( buffer.textview )            if self.bufferdata[pane].modified != 1:                self.undosequence.add_action( BufferModifiedAction(buffer, self) )            self.undosequence.add_action( BufferInsertionAction(buffer, it.get_offset(), text) )            self.undosequence.end_group()    def on_text_delete_range(self, buffer, it0, it1):        text = buffer.get_text(it0, it1, 0)        pane = self.textview.index(buffer.textview)        assert self.deleted_lines_pending == -1        self.deleted_lines_pending = text.count("\n")        if not self.undosequence_busy:            self.undosequence.begin_group()            if self.bufferdata[pane].modified != 1:                self.undosequence.add_action( BufferModifiedAction(buffer, self) )            self.undosequence.add_action( BufferDeletionAction(buffer, it0.get_offset(), text) )            self.undosequence.end_group()        #        #        #    def _get_focused_textview(self):        for i in range(self.num_panes):            t = self.textview[i]            if t.is_focus():                return t        return None    def on_find_activate(self, *args):        self.keymask = 0        self.queue_draw()        if self.find_dialog:            self.find_dialog.widget.present()        else:            class FindDialog(gnomeglade.Component):                def __init__(self, app):                    self.parent = app                    self.pane = -1                    gladefile = paths.share_dir("glade2/filediff.glade")                    gnomeglade.Component.__init__(self, gladefile, "finddialog")                    self.widget.set_transient_for(app.widget.get_toplevel())                    self.widget.show_all()                def on_destroy(self, *args):                    self.parent.find_dialog = None                    self.widget.destroy()                def on_entry_search_for_activate(self, *args):                    self.parent._find_text( self.entry_search_for.get_chars(0,-1),                        self.check_case.get_active(),                        self.check_word.get_active(),                        self.check_wrap.get_active(),                        self.check_regex.get_active() )                    return 1            self.find_dialog = FindDialog(self)    def on_find_next_activate(self, *args):        if self.last_search:            s = self.last_search            self._find_text(s.text, s.case, s.word, s.wrap, s.regex)        else:            self.on_find_activate()    def on_copy_activate(self, *extra):        t = self._get_focused_textview()        if t:            t.emit("copy-clipboard") #XXX .get_buffer().copy_clipboard()    def on_cut_activate(self, *extra):        t = self._get_focused_textview()        if t:            t.emit("cut-clipboard") #XXX get_buffer().cut_clipboard()    def on_paste_activate(self, *extra):        t = self._get_focused_textview()        if t:            t.emit("paste-clipboard") #XXX t.get_buffer().paste_clipboard(None, 1)    def on_textview_button_press_event(self, textview, event):        if event.button == 3:            textview.grab_focus()            pane = self.textview.index(textview)            self.popup_menu.popup_in_pane( pane )            return 1        return 0    def on_textview_toggle_overwrite(self, view):        self.textview_overwrite = not self.textview_overwrite        for v,h in zip(self.textview, self.textview_overwrite_handlers):            v.disconnect(h)            if v != view:                v.emit("toggle-overwrite")        self.textview_overwrite_handlers = [ t.connect("toggle-overwrite", self.on_textview_toggle_overwrite) for t in self.textview ]        self._update_cursor_status(view.get_buffer())        #        # find/replace buffer        #    def _find_text(self, tofind_utf8, match_case=0, entire_word=0, wrap=1, regex=0):        self.last_search = misc.struct(text=tofind_utf8, case=match_case, word=entire_word, wrap=wrap, regex=regex)        view = self._get_focused_textview() or self.textview0        buf = view.get_buffer()        insert = buf.get_iter_at_mark( buf.get_insert() )        tofind = tofind_utf8.decode("utf-8") # tofind is utf-8 encoded        text = buf.get_text(*buf.get_bounds() ).decode("utf-8") # as is buffer        if not regex:            tofind = re.escape(tofind)        if entire_word:            tofind = r'\b' + tofind + r'\b'        try:            pattern = re.compile( tofind, (match_case and re.M or (re.M|re.I)) )        except re.error, e:            misc.run_dialog( _("Regular expression error\n'%s'") % e, self, messagetype=gtk.MESSAGE_ERROR)        else:            match = pattern.search(text, insert.get_offset()+1)            if match == None and wrap:                match = pattern.search(text, 0)            if match:                it = buf.get_iter_at_offset( match.start() )                buf.place_cursor( it )                it.forward_chars( match.end() - match.start() )                buf.move_mark( buf.get_selection_bound(), it )                view.scroll_to_mark( buf.get_insert(), 0)            elif regex:                misc.run_dialog( _("The regular expression '%s' was not found.") % tofind_utf8, self, messagetype=gtk.MESSAGE_INFO)            else:                misc.run_dialog( _("The text '%s' was not found.") % tofind_utf8, self, messagetype=gtk.MESSAGE_INFO)        #        # text buffer loading/saving        #    def recompute_label(self):        filenames = []        for i in range(self.num_panes):            filenames.append( self._get_filename(i) )        shortnames = misc.shorten_names(*filenames)        for i in range(self.num_panes):            stock = None            if self.bufferdata[i].modified == 1:                shortnames[i] += "*"                if self.bufferdata[i].writable == 1:                    stock = gtk.STOCK_SAVE                else:                    stock = gtk.STOCK_SAVE_AS            elif self.bufferdata[i].writable == 0:                stock = gtk.STOCK_NO            if stock:                self.statusimage[i].show()                self.statusimage[i].set_from_stock(stock, gtk.ICON_SIZE_SMALL_TOOLBAR)            else:                self.statusimage[i].hide()        self.label_text = " : ".join(shortnames)        self.label_changed()    def set_files(self, files):        """Set num panes to len(files) and load each file given.           If an element is None, the text of a pane is left as is.        """        for i,f in enumerate(files):            if f:                b = self.textview[i].get_buffer()                b.delete( b.get_start_iter(), b.get_end_iter() )                absfile = os.path.abspath(f)                self.fileentry[i].set_filename(absfile)                self.bufferdata[i] = MeldBufferData(absfile)        self.recompute_label()        self.scheduler.add_task( self._set_files_internal(files).next )    def _set_files_internal(self, files):        yield _("[%s] Set num panes") % self.label_text        self.set_num_panes( len(files) )        self._disconnect_buffer_handlers()        self.linediffer.diffs = [[],[]]        self.queue_draw()        buffers = [t.get_buffer() for t in self.textview][:self.num_panes]        try_codecs = self.prefs.text_codecs.split()        yield _("[%s] Opening files") % self.label_text        panetext = ["\n"] * self.num_panes        tasks = []        for i,f in enumerate(files):            if f:                try:                    task = misc.struct(filename = f,                                       file = codecs.open(f, "rU", try_codecs[0]),                                       buf = buffers[i],                                       codec = try_codecs[:],                                       text = [],                                       pane = i)                    tasks.append(task)                except (IOError, LookupError), e:                    buffers[i].set_text("\n")                    misc.run_dialog(                        "%s\n\n%s\n%s" % (                            _("Could not read from '%s'") % f,                            _("The error was:"),                            str(e)),                        parent = self)            else:                panetext[i] = buffers[i].get_text( buffers[i].get_start_iter(), buffers[i].get_end_iter() )        yield _("[%s] Reading files") % self.label_text        while len(tasks):            for t in tasks[:]:                try:                    nextbit = t.file.read(4096)                    if nextbit.find("\x00") != -1:                        misc.run_dialog(                            "%s\n\n%s" % (                                _("Could not read from '%s'") % t.filename,                                _("It contains ascii nulls.\nPerhaps it is a binary file.") ),                                parent = self )                        t.buf.delete( t.buf.get_start_iter(), t.buf.get_end_iter() )                        tasks.remove(t)                except ValueError, err:                    t.codec.pop(0)                    if len(t.codec):                        t.file = codecs.open(t.filename, "rU", t.codec[0])                        t.buf.delete( t.buf.get_start_iter(), t.buf.get_end_iter() )                        t.text = []                    else:                        print "codec error fallback", err                        t.buf.delete( t.buf.get_start_iter(), t.buf.get_end_iter() )                        misc.run_dialog(                            "%s\n\n%s" % (                                _("Could not read from '%s'") % t.filename,                                _("I tried encodings %s.") % try_codecs ),                            parent = self)                        tasks.remove(t)                except IOError, ioerr:                    misc.run_dialog(                        "%s\n\n%s\n%s" % (                            _("Could not read from '%s'") % t.filename,                            _("The error was:"),                            str(ioerr)),                        parent = self)                    tasks.remove(t)                else:                    if len(nextbit):                        t.buf.insert( t.buf.get_end_iter(), nextbit )                        t.text.append(nextbit)                    else:                        self.set_buffer_writable(t.buf, os.access(t.filename, os.W_OK))                        self.bufferdata[t.pane].encoding = t.codec[0]                        if hasattr(t.file, "newlines"):                            self.bufferdata[t.pane].newlines = t.file.newlines                        tasks.remove(t)                        panetext[t.pane] = "".join(t.text)                        if len(panetext[t.pane]) and \                            panetext[t.pane][-1] != "\n" and \                            self.prefs.supply_newline:                                t.buf.insert( t.buf.get_end_iter(), "\n")                                panetext[t.pane] += "\n"            yield 1        self.undosequence.clear()        yield _("[%s] Computing differences") % self.label_text        panetext = [self._filter_text(p) for p in panetext]        lines = map(lambda x: x.split("\n"), panetext)        step = self.linediffer.set_sequences_iter(*lines)        while step.next() == None:            yield 1        self.queue_draw()        lenseq = [len(d) for d in self.linediffer.diffs]        self.scheduler.add_task( self._update_highlighting( (0,lenseq[0]), (0,lenseq[1]) ).next )        self._connect_buffer_handlers()        if sourceview_available:            for i in range(len(files)):                if files[i]:                    set_highlighting_enabled( self.textview[i].get_buffer(), files[i], self.prefs.use_syntax_highlighting )        yield 0    def _update_highlighting(self, range0, range1):        buffers = [t.get_buffer() for t in self.textview]        for b in buffers:            taglist = ["delete line", "conflict line", "replace line", "inline line"]            table = b.get_tag_table()            for tagname in taglist:                tag = table.lookup(tagname)                b.remove_tag(tag, b.get_start_iter(), b.get_end_iter() )        for chunk in self.linediffer.all_changes(self._get_texts()):            for i,c in enumerate(chunk):                if c and c[0] == "replace":                    bufs = buffers[1], buffers[i*2]                    #tags = [b.get_tag_table().lookup("replace line") for b in bufs]                    starts = [b.get_iter_at_line(l) for b,l in zip(bufs, (c[1],c[3])) ]                    text1 = "\n".join( self._get_texts(raw=1)[1  ][c[1]:c[2]] ).encode("utf16")                    text1 = struct.unpack("%iH"%(len(text1)/2), text1)[1:]                    textn = "\n".join( self._get_texts(raw=1)[i*2][c[3]:c[4]] ).encode("utf16")                    textn = struct.unpack("%iH"%(len(textn)/2), textn)[1:]                    matcher = difflib.SequenceMatcher(None, text1, textn)                    #print "<<<\n%s\n---\n%s\n>>>" % (text1, textn)                    tags = [b.get_tag_table().lookup("inline line") for b in bufs]                    back = (0,0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -