All Projects → ZSaberLv0 → Zfvimdirdiff

ZSaberLv0 / Zfvimdirdiff

vim script to diff two directories like BeyondCompare by using `diff`

Projects that are alternatives of or similar to Zfvimdirdiff

React Checkbox Tree
A simple and elegant checkbox tree for React.
Stars: ✭ 477 (+2068.18%)
Mutual labels:  treeview
Daff
align and compare tables
Stars: ✭ 598 (+2618.18%)
Mutual labels:  diff
Diffdom
A diff for DOM elements, as client-side JavaScript code. Gets all modifications, insertions and removals between two DOM fragments.
Stars: ✭ 660 (+2900%)
Mutual labels:  diff
Ete
Python package for building, comparing, annotating, manipulating and visualising trees. It provides a comprehensive API and a collection of command line tools, including utilities to work with the NCBI taxonomy tree.
Stars: ✭ 506 (+2200%)
Mutual labels:  treeview
Datasources
💾 🔜📱 Type-safe data-driven CollectionView, TableView Framework. (We can also use ASCollectionNode)
Stars: ✭ 553 (+2413.64%)
Mutual labels:  diff
Nanomorph
🚅 - Hyper fast diffing algorithm for real DOM nodes
Stars: ✭ 621 (+2722.73%)
Mutual labels:  diff
Hdiffpatch
a C\C++ library and command-line tools for Diff & Patch between binary files or directories(folder); cross-platform; run fast; create small delta/differential; support large files and limit memory requires when diff & patch.
Stars: ✭ 459 (+1986.36%)
Mutual labels:  diff
Dbkoda
State of the art MongoDB IDE
Stars: ✭ 795 (+3513.64%)
Mutual labels:  treeview
Changedetection
Automatically track websites changes on Android in background.
Stars: ✭ 563 (+2459.09%)
Mutual labels:  diff
React Diff Viewer
A simple and beautiful text diff viewer component made with Diff and React.
Stars: ✭ 642 (+2818.18%)
Mutual labels:  diff
Happo
Visual diffing in CI for user interfaces
Stars: ✭ 510 (+2218.18%)
Mutual labels:  diff
Patch Package
Fix broken node modules instantly 🏃🏽‍♀️💨
Stars: ✭ 6,062 (+27454.55%)
Mutual labels:  diff
Sirix
SirixDB is a temporal, evolutionary database system, which uses an accumulate only approach. It keeps the full history of each resource. Every commit stores a space-efficient snapshot through structural sharing. It is log-structured and never overwrites data. SirixDB uses a novel page-level versioning approach called sliding snapshot.
Stars: ✭ 638 (+2800%)
Mutual labels:  diff
Folder Explorer
分析文件目录,统计数据并以树形结构和图表的形式展示结果,也可以导出多种格式留存
Stars: ✭ 479 (+2077.27%)
Mutual labels:  treeview
Java Diff Utils
Diff Utils library is an OpenSource library for performing the comparison / diff operations between texts or some kind of data: computing diffs, applying patches, generating unified diffs or parsing them, generating diff output for easy future displaying (like side-by-side view) and so on.
Stars: ✭ 670 (+2945.45%)
Mutual labels:  diff
Vue Jstree
A Tree Plugin For Vue2.0+
Stars: ✭ 469 (+2031.82%)
Mutual labels:  treeview
Diffabledatasources
💾 A library for backporting UITableView/UICollectionViewDiffableDataSource.
Stars: ✭ 601 (+2631.82%)
Mutual labels:  diff
Changeset
Minimal edits from one collection to another
Stars: ✭ 807 (+3568.18%)
Mutual labels:  diff
Java Object Diff
Library to diff and merge Java objects with ease
Stars: ✭ 725 (+3195.45%)
Mutual labels:  diff
Xcdiff
A tool which helps you diff xcodeproj files.
Stars: ✭ 641 (+2813.64%)
Mutual labels:  diff

ZFVimDirDiff

vim plugin to diff two directories like BeyondCompare by using diff

inspired by will133/vim-dirdiff

  • why another directory diffing plugin?

    • format the diff result as vertical split file tree view, which should be more human-readable
    • more friendly file sync operation using the same mappings as builtin vimdiff
    • automatically backup before destructive actions (by ZFVimBackup)
    • better file or directory exclude logic (by ZFVimIgnore)

if you like my work, check here for a list of my vim plugins, or buy me a coffee

how to use

  1. install by vim-plug or any other plugin manager:

    Plug 'ZSaberLv0/ZFVimDirDiff'
    Plug 'ZSaberLv0/ZFVimIgnore' " required only if you want to use default g:ZFDirDiffFileExclude settings
    Plug 'ZSaberLv0/ZFVimBackup' " required only if you want to enable auto backup
    
  2. use :ZFDirDiff command to start diff

    :ZFDirDiff pathA pathB
    

    if path contains spaces:

    :ZFDirDiff path\ A path\ B
    :call ZF_DirDiff("path A", "path B")
    
  3. use :ZFDirDiffMark to mark two directories to start diff

    Open a file and :ZFDirDiffMark and the containing directory will be stored as a diff candidate. Then repeat with another file and you'll be asked to diff the two.

    :edit pathA/file.vim
    :ZFDirDiffMark
    :edit pathB/file.vim
    :ZFDirDiffMark
    

    Or integrate with your file manager. For vim-dirvish, add ~/.vim/ftplugin/dirvish.vim:

     nnoremap <buffer> X :<C-u>ZFDirDiffMark <C-r><C-l><CR>
    

    Or for netrw, add ~/.vim/ftplugin/netrw.vim:

     nnoremap <buffer> X :<C-u>ZFDirDiffMark <C-r>=b:netrw_curdir<CR>/<C-r><C-l><CR>
    

    Then X on two directories.

  4. you can also start diff from scrooloose/nerdtree: inside nerdtree window, press m to popup menu, press z to choose mark to diff, and mark another node again to start diff

  5. you may also use it as command line diff tool

    vim -c 'call ZF_DirDiff("path A", "path B")'
    sh ZFDirDiff.sh "path A" "path B"
    
  6. within the diff window:

    • use DD to update the diff result
    • use o or <cr> to diff current file, or fold/unfold current dir
    • use O to unfold all contents under current dir, x to fold to parent, X to fold to root
    • use cd to make current dir as diff root dir, u to go up for current side, and U to go up for both side
    • use DM to mark current file, and DM again on another file to diff these two files
    • use ]c or DJ to move to next diff, [c or DK to prev diff
    • use do or DH to sync from another side to current side, dp or DL to sync from current side to another side
    • use dd to delete node under cursor
    • use DN to mark mutiple files, when done, use do/DH/dp/DL/dd to sync or delete marked files
    • use p to copy the node's path, and P for the node's full path
    • use q to exit diff
    • you may also want to use ZSaberLv0/ZFVimIndentMove or easymotion/vim-easymotion to quickly move between file tree node

autocmds and buffer local vars

  • ZFDirDiff_DirDiffEnter

    called when enter dir diff buffer (each time for left and right window buffer)

    buffer local vars:

    • t:ZFDirDiff_ownerTab : tabpagenr() that open the diff task

    • t:ZFDirDiff_fileLeft : abs path of left dir

    • t:ZFDirDiff_fileRight : abs path of right dir

    • t:ZFDirDiff_fileLeftOrig : original path passed from param

    • t:ZFDirDiff_fileRightOrig : original path passed from param

    • t:ZFDirDiff_hasDiff : whether has diff

    • t:ZFDirDiff_data : data return from ZF_DirDiffCore()

      [
          {
              'level' : 'depth of tree node, 0 for top most ones',
              'path' : 'path relative to fileLeft/fileRight',
              'name' : 'file or dir name, empty if fileLeft and fileRight is file',
              'type' : '',
                  // T_DIR: current node is dir
                  // T_SAME: current node is file and has no diff
                  // T_DIFF: current node is file and has diff
                  // T_DIR_LEFT: only left exists and it is dir
                  // T_DIR_RIGHT: only right exists and it is dir
                  // T_FILE_LEFT: only left exists and it is dir
                  // T_FILE_RIGHT: only right exists and it is dir
                  // T_CONFLICT_DIR_LEFT: left is dir and right is file
                  // T_CONFLICT_DIR_RIGHT: left is file and right is dir
              'diff' : '0/1, whether this node or children node contains diff',
              'children' : [
                  ...
              ],
          },
          ...
      ]
      
    • t:ZFDirDiff_dataUI : list of each line for building UI

      this is a plain list including folded item, you may also use t:ZFDirDiff_dataUIVisible for visible item list

      [{
          'index' : 'index in t:ZFDirDiff_dataUI',
          'indexVisible' : 'index in t:ZFDirDiff_dataUIVisible, -1 when not visible',
          'folded' : 'true when this item is dir and folded',
          'data' : {
              // original data of t:ZFDirDiff_data
              ...
          },
      }]
      
    • b:ZFDirDiff_isLeft : true if cur buffer is left

    • b:ZFDirDiff_iLineOffset : first item's offset accorrding to header lines

  • ZFDirDiff_FileDiffEnter

    called when enter file diff buffer (each time for left and right window buffer)

    buffer local vars:

    • t:ZFDirDiff_ownerDiffTab : tabpagenr() of owner diff buffer that open this file diff task

configs

  • for core logic:
    • let g:ZFDirDiffShowSameFile = 1 : whether to show files that are same

    • let g:ZFDirDiffFileExclude = '' : file name exclude pattern, e.g. *.class,*.o

      it's recommended to use Plug 'ZSaberLv0/ZFVimIgnore' for ignore settings, you may disable this by let g:ZFDirDiffFileExcludeUseDefault=0

    • function! ZFDirDiffCustomFilter(path, type)

      if you want to supply custom filter logic, define a function named ZFDirDiffCustomFilter before :ZFDirDiff

      function! ZFDirDiffCustomFilter(path, type)
          if match(path, 'xxx') >= 0
              " return 1 to ignore this item
              return 1
          else
              return 0
          endif
      endfunction
      

      NOTE: the filter function affects all :ZFDirDiff after defined, you may want to delfunction! ZFDirDiffCustomFilter after :ZFDirDiff call

    • let g:ZFDirDiffContentExclude = '' : file content exclude pattern, e.g. log:,id:

    • let g:ZFDirDiffFileIgnoreCase = 0 : whether ignore file name case

    • let g:ZFDirDiffCustomDiffArg = '' : additional diff args passed to diff

    • let g:ZFDirDiffSortFunc = 'ZF_DirDiffSortFunc' : sort function

  • for builtin UI impl:
    • let g:ZFDirDiffUI_filetypeLeft = 'ZFDirDiffLeft' : filetype for left diff buffer

    • let g:ZFDirDiffUI_filetypeRight = 'ZFDirDiffRight' : filetype for right diff buffer

    • let g:ZFDirDiffUI_tabstop = 2 : tabstop for diff buffer

    • let g:ZFDirDiffUI_headerTextFunc = 'YourFunc' : function name to get the header text

      " return a list of strings - one per line
      function! YourFunc()
          if b:ZFDirDiff_isLeft
              return [t:ZFDirDiff_fileLeft, '']
          else
              return [t:ZFDirDiff_fileRight, '']
          endif
      endfunction
      
    • let g:ZFDirDiffUI_confirmHintHeaderFunc = 'YourFunc' : function name to get the header text for confirmation prompts

      • type:
        • 'l2r' : sync left to right
        • 'r2l' : sync right to left
        • 'dl' : delete left
        • 'dr' : delete right
        • 'diff' : diff two path
      " return a list of strings - one per line
      function! YourFunc(fileLeft, fileRight, type)
          return ['LEFT: ' . a:fileLeft, 'RIGHT: ' . a:fileRight]
      endfunction
      
    • let g:ZFDirDiffUI_autoBackup = 1 or let t:ZFDirDiffUI_autoBackup = 1 : whether backup before write or delete files, require ZSaberLv0/ZFVimBackup installed

    • let g:ZFDirDiffUI_syncSameFile = 0 : whether need to sync same file, can be local to tab t:ZFDirDiffUI_syncSameFile

    • whether confirm before sync (can be local to tab t:xxx)

      • let g:ZFDirDiffConfirmSyncDir = 1
      • let g:ZFDirDiffConfirmSyncFile = 1
      • let g:ZFDirDiffConfirmCopyDir = 1
      • let g:ZFDirDiffConfirmCopyFile = 0
      • let g:ZFDirDiffConfirmRemoveDir = 1
      • let g:ZFDirDiffConfirmRemoveFile = 1
    • keymaps

      • let g:ZFDirDiffKeymap_update = ['DD']
      • let g:ZFDirDiffKeymap_open = ['<cr>', 'o']
      • let g:ZFDirDiffKeymap_foldOpenAll = ['O']
      • let g:ZFDirDiffKeymap_foldClose = ['x']
      • let g:ZFDirDiffKeymap_foldCloseAll = ['X']
      • let g:ZFDirDiffKeymap_goParent = ['U']
      • let g:ZFDirDiffKeymap_diffThisDir = ['cd']
      • let g:ZFDirDiffKeymap_diffParentDir = ['u']
      • let g:ZFDirDiffKeymap_markToDiff = ['DM']
      • let g:ZFDirDiffKeymap_markToSync = ['DN']
      • let g:ZFDirDiffKeymap_quit = ['q']
      • let g:ZFDirDiffKeymap_quitFileDiff = ['q']
      • let g:ZFDirDiffKeymap_nextDiff = [']c', 'DJ']
      • let g:ZFDirDiffKeymap_prevDiff = ['[c', 'DK']
      • let g:ZFDirDiffKeymap_syncToHere = ['do', 'DH']
      • let g:ZFDirDiffKeymap_syncToThere = ['dp', 'DL']
      • let g:ZFDirDiffKeymap_deleteFile = ['dd']
      • let g:ZFDirDiffKeymap_getPath = ['p']
      • let g:ZFDirDiffKeymap_getFullPath = ['P']
    • highlight

      highlight link ZFDirDiffHL_Title Title
      highlight link ZFDirDiffHL_Dir Directory
      highlight link ZFDirDiffHL_DirContainDiff Directory
      highlight link ZFDirDiffHL_Same Folded
      highlight link ZFDirDiffHL_Diff DiffText
      highlight link ZFDirDiffHL_DirOnlyHere DiffAdd
      highlight link ZFDirDiffHL_DirOnlyThere Normal
      highlight link ZFDirDiffHL_FileOnlyHere DiffAdd
      highlight link ZFDirDiffHL_FileOnlyThere Normal
      highlight link ZFDirDiffHL_ConflictDir ErrorMsg
      highlight link ZFDirDiffHL_ConflictFile WarningMsg
      highlight link ZFDirDiffHL_MarkToDiff Cursor
      

FAQ

  • Q: how to use under special shell config

    A: when used under special shell config, especially sh under Windows, here's a list of configs you should concern:

    • let g:ZFDirDiffLangString = 'LANG= '

      by default, this value is set to set LAND= && on Windows to suit cmd.exe

      you may want to set this to suit your shell, e.g.

      let g:ZFDirDiffLangString = 'LANG= '
      
    • ZF_DirDiffTempname()

      by default, this function use vim's builtin tempname()

      however, it may result to C:\xxx\tmp on Windows, which can not be read by bash, you may want to supply your own function to suit your shell, e.g.

      function! ZF_DirDiffTempname()
          return '/xxx/tmp'
      endfunction
      
    • ZF_DirDiffShellEnv_pathFormat(path)

      by default, this function use fnamemodify(path, ':.') to make the path relative to getcwd()

      if your shell can't read with it, you may supply your own, e.g.

      function! ZF_DirDiffShellEnv_pathFormat(path)
          return substitute(system('cygpath -m "' . a:path . '"'), '[\r\n]', '', 'g')
      endfunction
      
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].