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

📄 filediff.py

📁 一份linux上的比较工具meld的源代码
💻 PY
📖 第 1 页 / 共 5 页
字号:
        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)                    for o in matcher.get_opcodes():                        if o[0] == "equal":                            if (o[2]-o[1] < 3) or (o[4]-o[3] < 3):                                back = o[4]-o[3], o[2]-o[1]                            continue                        for i in range(2):                            s,e = starts[i].copy(), starts[i].copy()                            s.forward_chars( o[1+2*i] - back[i] )                            e.forward_chars( o[2+2*i] )                            bufs[i].apply_tag(tags[i], s, e)                        back = (0,0)                    yield 1    def on_textview_expose_event(self, textview, event):        if self.num_panes == 1:            return        if event.window != textview.get_window(gtk.TEXT_WINDOW_TEXT) \            and event.window != textview.get_window(gtk.TEXT_WINDOW_LEFT):            return        if not hasattr(textview, "meldgc"):            self._setup_gcs(textview)        visible = textview.get_visible_rect()        pane = self.textview.index(textview)        start_line = self._pixel_to_line(pane, visible.y)        end_line = 1+self._pixel_to_line(pane, visible.y+visible.height)        gc = lambda x : getattr(textview.meldgc, "gc_"+x)        #gcdark = textview.get_style().black_gc        gclight = textview.get_style().bg_gc[gtk.STATE_ACTIVE]        #curline = textview.get_buffer().get_iter_at_mark( textview.get_buffer().get_insert() ).get_line()                       def draw_change(change): # draw background and thin lines            ypos0 = self._line_to_pixel(pane, change[1]) - visible.y            width = event.window.get_size()[0]            #gcline = (gclight, gcdark)[change[1] <= curline and curline < change[2]]            gcline = gclight            event.window.draw_line(gcline, 0,ypos0-1, width,ypos0-1)            if change[2] != change[1]:                ypos1 = self._line_to_pixel(pane, change[2]) - visible.y                event.window.draw_line(gcline, 0,ypos1, width,ypos1)                event.window.draw_rectangle(gc(change[0]), 1, 0,ypos0, width,ypos1-ypos0)        last_change = None        for change in self.linediffer.single_changes(pane, self._get_texts()):            if change[2] < start_line: continue            if change[1] > end_line: break            if last_change and change[1] <= last_change[2]:                last_change = ("conflict", last_change[1], max(last_change[2],change[2]))            else:                if last_change:                    draw_change(last_change)                last_change = change        if last_change:            draw_change(last_change)            def _get_filename_for_saving(self, title ):        dialog = gtk.FileChooserDialog(title,            parent=self.widget.get_toplevel(),            action=gtk.FILE_CHOOSER_ACTION_SAVE,            buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK) )        dialog.set_default_response(gtk.RESPONSE_OK)        response = dialog.run()        filename = None        if response == gtk.RESPONSE_OK:            filename = dialog.get_filename()        dialog.destroy()        if filename:            if os.path.exists(filename):                response = misc.run_dialog(                    _('"%s" exists!\nOverwrite?') % os.path.basename(filename),                    parent = self,                    buttonstype = gtk.BUTTONS_YES_NO)                if response == gtk.RESPONSE_NO:                    return None            return filename        return None    def _save_text_to_filename(self, filename, text):        try:            open(filename, "w").write(text)        except IOError, e:            misc.run_dialog(                _("Error writing to %s\n\n%s.") % (filename, e),                self, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK)            return False        return True    def save_file(self, pane, saveas=0):        buf = self.textview[pane].get_buffer()        bufdata = self.bufferdata[pane]        if saveas or not bufdata.filename:            filename = self._get_filename_for_saving( _("Choose a name for buffer %i.") % (pane+1) )            if filename:                bufdata.filename = bufdata.label = os.path.abspath(filename)                self.fileentry[pane].set_filename( bufdata.filename)            else:                return melddoc.RESULT_ERROR        text = buf.get_text(buf.get_start_iter(), buf.get_end_iter(), 0)        if bufdata.newlines:            if type(bufdata.newlines) == type(""):                if(bufdata.newlines) != '\n':                    text = text.replace("\n", bufdata.newlines)            elif type(bufdata.newlines) == type(()):                buttons = {'\n':("UNIX (LF)",0), '\r\n':("DOS (CR-LF)", 1), '\r':("MAC (CR)",2) }                newline = misc.run_dialog( _("This file '%s' contains a mixture of line endings.\n\nWhich format would you like to use?") % bufdata.label,                    self, gtk.MESSAGE_WARNING, buttonstype=gtk.BUTTONS_CANCEL,                    extrabuttons=[ buttons[b] for b in bufdata.newlines ] )                if newline < 0:                    return                for k,v in buttons.items():                    if v[1] == newline:                        bufdata.newlines = k                        if k != '\n':                            text = text.replace('\n', k)                        break        if bufdata.encoding and self.prefs.save_encoding==0:            try:                text = text.encode(bufdata.encoding)            except UnicodeEncodeError:                if misc.run_dialog(                    _("'%s' contains characters not encodable with '%s'\nWould you like to save as UTF-8?") % (bufdata.label, bufdata.encoding),                    self, gtk.MESSAGE_ERROR, gtk.BUTTONS_YES_NO) != gtk.RESPONSE_YES:                    return melddoc.RESULT_ERROR        if self._save_text_to_filename(bufdata.filename, text):            self.emit("file-changed", bufdata.filename)            self.undosequence.clear()            self.set_buffer_modified(buf, 0)            return melddoc.RESULT_OK        else:            return melddoc.RESULT_ERROR    def make_patch(self, pane):        fontdesc = pango.FontDescription(self.prefs.get_current_font())        override = {}        if sourceview_available:            override["GtkTextView"] = gsv.SourceView            override["GtkTextBuffer"] = gsv.SourceBuffer        dialog = gnomeglade.Component( paths.share_dir("glade2/filediff.glade"), "patchdialog", override)        dialog.widget.set_transient_for( self.widget.get_toplevel() )        bufs = [t.get_buffer() for t in self.textview]        texts = [b.get_text(*b.get_bounds()).split("\n") for b in bufs]        texts[0] = [l+"\n" for l in texts[0]]        texts[1] = [l+"\n" for l in texts[1]]        names = [self._get_pane_label(i) for i in range(2)]        prefix = os.path.commonprefix( names )        try: prefixslash = prefix.rindex("/") + 1        except ValueError: prefixslash = 0        names = [n[prefixslash:] for n in names]        if sourceview_available:            dialog.textview.set_buffer( gsv.SourceBuffer() )        dialog.textview.modify_font(fontdesc)        buf = dialog.textview.get_buffer()        lines = []        for line in difflib.unified_diff(texts[0], texts[1], names[0], names[1]):            buf.insert( buf.get_end_iter(), line )            lines.append(line)        if sourceview_available:            man = gsv.SourceLanguagesManager()            gsl = man.get_language_from_mime_type("text/x-diff")            if gsl:                buf.set_language(gsl)                buf.set_highlight(True)        result = dialog.widget.run()        dialog.widget.destroy()        if result >= 0:            txt = buf.get_text(buf.get_start_iter(), buf.get_end_iter(), 0)            if result == 1: # copy                clip = gtk.clipboard_get()                clip.set_text(txt)                clip.store()            else:# save as                filename = self._get_filename_for_saving( _("Save patch as...") )                if filename:                    self._save_text_to_filename(filename, txt)

⌨️ 快捷键说明

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