├── autoload └── partedit.vim ├── doc └── partedit.txt └── plugin └── partedit.vim /autoload/partedit.vim: -------------------------------------------------------------------------------- 1 | " Edits part of buffer by another buffer. 2 | " Version: 1.2 3 | " Author : thinca 4 | " License: zlib License 5 | 6 | let s:save_cpo = &cpo 7 | set cpo&vim 8 | 9 | function! partedit#command(startline, endline, args) 10 | let options = {} 11 | let rest = a:args 12 | while rest =~# '^\s*-\w\+' 13 | let [opt, rest] = matchlist(rest, '^\s*-\(\w\+\)\s*\(.*\)')[1 : 2] 14 | if rest[0] =~# '["'']' 15 | let q = rest[0] 16 | let rest = rest[1 :] 17 | let pos = match(rest, '\\\@ 88 | autocmd BufWriteCmd nested call s:apply() 89 | autocmd BufWipeout nested 90 | \ call setbufvar(b:partedit__bufnr, '&bufhidden', b:partedit__bufhidden) 91 | augroup END 92 | endfunction 93 | 94 | function! s:apply() 95 | let [start, end] = b:partedit__lines 96 | let curpos = exists('*getcurpos') ? getcurpos() : getpos('.') 97 | 98 | if !v:cmdbang && 99 | \ b:partedit__contents != getbufline(b:partedit__bufnr, start, end) 100 | " TODO: Takes a proper step. 101 | let all = getbufline(b:partedit__bufnr, 1, '$') 102 | let line = s:search_partial(all, b:partedit__contents, start) + 1 103 | if line 104 | let [start, end] = [line, line + end - start] 105 | 106 | else 107 | echo 'The range in the original buffer was changed. Overwrite? [yN]' 108 | if nr2char(getchar()) !~? 'y' 109 | return 110 | endif 111 | endif 112 | endif 113 | 114 | let contents = getline(1, '$') 115 | if b:partedit__prefix !=# '' 116 | let prefix = b:partedit__prefix 117 | let sprefix = substitute(prefix, '\s\+$', '', '') 118 | call map(contents, '(v:val ==# "" ? sprefix : prefix) . v:val') 119 | endif 120 | let bufnr = bufnr('%') 121 | 122 | setlocal bufhidden=hide 123 | noautocmd execute 'keepjumps' b:partedit__bufnr 'buffer' 124 | 125 | let modified = &l:modified 126 | 127 | silent execute printf('%d,%d delete _', start, end) 128 | silent execute start - 1 'put' '=contents' 129 | 130 | if &l:buftype =~# '^\%(\|acwrite\)$' && !modified 131 | write 132 | endif 133 | 134 | noautocmd execute 'keepjumps hide' bufnr 'buffer' 135 | setlocal bufhidden=wipe 136 | 137 | let b:partedit__contents = contents 138 | let b:partedit__lines = [start, start + len(contents) - 1] 139 | setlocal nomodified 140 | call setpos('.', curpos) 141 | endfunction 142 | 143 | function! s:search_partial(all, part, base) 144 | let l = len(a:part) 145 | let last = len(a:all) 146 | let s:base = a:base 147 | for n in sort(range(last), 's:sort') 148 | if n + l <= last && a:all[n] == a:part[0] && 149 | \ a:all[n : n + l - 1] == a:part 150 | return n 151 | end 152 | endfor 153 | return -1 154 | endfunction 155 | 156 | function! s:sort(a, b) 157 | return abs(a:a - s:base) - abs(a:b - s:base) 158 | endfunction 159 | 160 | function! s:get_option(name, base, default) 161 | if has_key(a:base, a:name) 162 | return a:base[a:name] 163 | endif 164 | if exists('b:partedit_' . a:name) 165 | return b:partedit_{a:name} 166 | endif 167 | if exists('g:partedit#' . a:name) 168 | return g:partedit#{a:name} 169 | endif 170 | return a:default 171 | endfunction 172 | 173 | function! s:trim_contents(contents, prefix, auto_prefix, prefix_pattern,) 174 | let contents = copy(a:contents) 175 | let prefix = a:prefix 176 | 177 | if a:prefix_pattern !=# '' 178 | let prefix_provisional = '' 179 | let len_prefix = -1 180 | 181 | for line in contents 182 | if line =~# '^' . a:prefix_pattern . '\v$' 183 | continue 184 | endif 185 | if len_prefix > 0 186 | let line = line[: len_prefix - 1] 187 | endif 188 | let prefix_provisional = matchstr(line, '^' . a:prefix_pattern) 189 | let len_prefix = strlen(prefix_provisional) 190 | if len_prefix == 0 191 | break 192 | endif 193 | endfor 194 | 195 | call map(contents, 'v:val[len_prefix :]') 196 | let prefix = prefix_provisional 197 | 198 | else 199 | 200 | if prefix !=# '' 201 | let sprefix = substitute(prefix, '\s\+$', '', '') 202 | let len = len(sprefix) 203 | let pos = len - 1 204 | let all_prefix_exists = 1 205 | for line in contents 206 | if line[: pos] !=# sprefix 207 | let all_prefix_exists = 0 208 | break 209 | endif 210 | endfor 211 | if all_prefix_exists 212 | let pat = '^' . substitute(prefix, '\s\+$', '\\%(\0\\|$\\)', '') 213 | call map(contents, 'substitute(v:val, pat, "", "")') 214 | else 215 | let prefix = '' 216 | endif 217 | endif 218 | if prefix ==# '' && a:auto_prefix && 2 <= len(contents) 219 | let prefix = contents[0] 220 | for line in contents[1 :] 221 | if line ==# '' 222 | continue 223 | endif 224 | let pat = escape(substitute(line, '.', '[\0]', 'g'),'\') 225 | let prefix = matchstr(prefix, '^\%[' . pat . ']') 226 | if prefix ==# '' 227 | break 228 | endif 229 | endfor 230 | if prefix !=# '' 231 | let len = len(prefix) 232 | call map(contents, 'v:val[len :]') 233 | endif 234 | endif 235 | 236 | endif 237 | 238 | return [contents, prefix] 239 | endfunction 240 | 241 | 242 | let &cpo = s:save_cpo 243 | unlet s:save_cpo 244 | -------------------------------------------------------------------------------- /doc/partedit.txt: -------------------------------------------------------------------------------- 1 | *partedit.txt* Edits part of buffer by another buffer. 2 | 3 | Version: 1.2 4 | Author : thinca 5 | License: zlib License 6 | 7 | ============================================================================== 8 | CONTENTS *partedit-contents* 9 | 10 | INTRODUCTION |partedit-introduction| 11 | INTERFACE |partedit-interface| 12 | COMMANDS |partedit-commands| 13 | FUNCTIONS |partedit-functions| 14 | LIMITATION |partedit-limitation| 15 | CHANGELOG |partedit-changelog| 16 | 17 | 18 | ============================================================================== 19 | INTRODUCTION *partedit-introduction* 20 | 21 | *partedit* is a Vim plugin to edit a part of a buffer with another buffer. 22 | You can start to edit a part of the buffer with |:Partedit|. And you can 23 | apply the changes by saving the buffer. 24 | 25 | 26 | 27 | ============================================================================== 28 | INTERFACE *partedit-interface* 29 | 30 | ------------------------------------------------------------------------------ 31 | COMMANDS *partedit-commands* 32 | 33 | :[range]Partedit [options]... *:Partedit* 34 | :[range]Partedit [opener] 35 | Starts editing a part of a buffer. [range] of default is current 36 | line. 37 | [options] is pair of -option-name and value, such as following. > 38 | 39 | :Partedit -opener new -filetype vim -prefix "> " 40 | < 41 | If the argument is not started with "-", it is [opener]. 42 | 43 | :ParteditEnd *:ParteditEnd* 44 | This is available in the partedit buffer. 45 | Opens the original buffer in current window. 46 | 47 | ------------------------------------------------------------------------------ 48 | FUNCTIONS *partedit-functions* 49 | 50 | *partedit#start()* 51 | partedit#start({startline}, {endline} [, {options}]) 52 | Function version of |:Partedit|. 53 | {options} is a |Dictionary| which contains the following items: 54 | 55 | "opener" 56 | Overwrites |g:partedit#opener| and |b:partedit_opener|. 57 | "prefix" 58 | Overwrites |g:partedit#prefix| and |b:partedit_prefix|. 59 | "filetype" 60 | Overwrites |g:partedit#filetype| and |b:partedit_filetype|. 61 | "auto_prefix" 62 | Overwrites |g:partedit#auto_prefix| and 63 | |b:partedit_auto_prefix|. 64 | 65 | 66 | 67 | ============================================================================== 68 | CUSTOMIZING *partedit-customizing* 69 | 70 | g:partedit#opener *g:partedit#opener* 71 | b:partedit_opener *b:partedit_opener* 72 | The partedit buffer is opened by this command such as |:new|, 73 | |:vsplit|, and so on. If omitted, |:edit| is used. 74 | If the value is starts with "=", it is treated as |expr|, and result 75 | is a opener. 76 | 77 | g:partedit#prefix *g:partedit#prefix* 78 | b:partedit_prefix *b:partedit_prefix* 79 | If this value is not empty, and each lines start with this string, 80 | this plugin removes common prefix on partedit buffer. 81 | The prefix is restored on original buffer. 82 | The blank of the end of a prefix is adjusted by good taste. 83 | > 84 | let b:partedit_prefix = '> ' 85 | 86 | === original buffer === 87 | > This is a sample text. 88 | > 89 | > Upper line has prefix ">", not "> ". But this is OK. 90 | 91 | === partedit buffer === 92 | This is a sample text. 93 | 94 | Upper line has prefix ">", not "> ". But this is OK. 95 | 96 | | edit 97 | v 98 | === partedit buffer === 99 | This is a sample text. 100 | 101 | Upper line has prefix ">", not "> ". But this is OK. 102 | 103 | All texts are restored with "> " prefix, 104 | but blank of the end of empty line is removed. 105 | 106 | === original buffer === 107 | > This is a sample text. 108 | > 109 | > Upper line has prefix ">", not "> ". But this is OK. 110 | > 111 | > All texts are restored with "> " prefix, 112 | > but blank of the end of empty line is removed. 113 | 114 | g:partedit#prefix_pattern *g:partedit#prefix_pattern* 115 | b:partedit_prefix_pattern *b:partedit_prefix_pattern* 116 | Similar to |b:partedit_prefix|, but this option can be specified by a 117 | regex. If this value is not empty, the common prefix of range that 118 | matches the specified regex is treated as prefix. With this option 119 | set, |b:partedit_prefix| and |b:partedit_auto_prefix| are ignored. 120 | The longest common string satisfying the given regex is treated as a 121 | prefix, and it is restored to the original buffer after editing the 122 | partedit buffer. 123 | > 124 | let b:partedit_prefix = '\v\s*//[/!]?\s*' 125 | 126 | === original buffer === 127 | // This is a sample comment. 128 | // 129 | // Upper line has prefix "//", not "// ". But this is OK. 130 | 131 | === partedit buffer === 132 | This is a sample comment. 133 | 134 | Upper line has prefix "//", not "// ". But this is OK. 135 | 136 | | edit 137 | v 138 | === partedit buffer === 139 | This is a sample text. 140 | 141 | Upper line has prefix "//", not "// ". But this is OK. 142 | 143 | All texts are restored with "// " prefix, 144 | but blank of the end of empty line is removed. 145 | 146 | === original buffer === 147 | // This is a sample text. 148 | // 149 | // Upper line has prefix "//", not "// ". But this is OK. 150 | // 151 | // All texts are restored with "// " prefix, 152 | // but blank of the end of empty line is removed. 153 | 154 | === original buffer === 155 | //! This is a sample documentation text. 156 | //! 157 | //! Upper line has prefix "//!", not "//! ". But this is OK. 158 | 159 | === partedit buffer === 160 | This is a sample documentation text. 161 | 162 | Upper line has prefix "//!", not "//! ". But this is OK. 163 | 164 | | edit 165 | v 166 | === partedit buffer === 167 | This is a sample documentation text. 168 | 169 | Upper line has prefix "//!", not "//! ". But this is OK. 170 | 171 | All texts are restored with "//! " prefix, 172 | but blank of the end of empty line is removed. 173 | 174 | === original buffer === 175 | //! This is a sample documentation text. 176 | //! 177 | //! Upper line has prefix "//!", not "//! ". But this is OK. 178 | //! 179 | //! All texts are restored with "//! " prefix, 180 | //! but blank of the end of empty line is removed. 181 | 182 | 183 | g:partedit#filetype *g:partedit#filetype* 184 | b:partedit_filetype *b:partedit_filetype* 185 | If this variable exists, 'filetype' of newly opened partedit buffer 186 | becomes this value. 187 | 188 | g:partedit#auto_prefix *g:partedit#auto_prefix* 189 | b:partedit_auto_prefix *b:partedit_auto_prefix* 190 | If this is true, and both |b:partedit_prefix| and 191 | |b:partedit_prefix_pattern| are empty, the common prefix of range is 192 | treated as prefix. The default value is true. 193 | 194 | 195 | 196 | ============================================================================== 197 | LIMITATION *partedit-limitation* 198 | 199 | - If you edit the original buffer, it will be not likely to be able to apply 200 | well. 201 | 202 | 203 | 204 | ============================================================================== 205 | CHANGELOG *partedit-changelog* 206 | 207 | 1.2 2012-11-27 208 | - Use same 'fileencoding' and 'fileformat' in partedit buffer. 209 | - `:Partedit [opener]` support. 210 | 211 | 1.1 2012-10-19 212 | - Add `prefix` feature. 213 | - Add some options. 214 | - |g:partedit#opener| |b:partedit_opener| 215 | - |g:partedit#prefix| |b:partedit_prefix| 216 | - |g:partedit#filetype| |b:partedit_filetype| 217 | - |g:partedit#auto_prefix| |b:partedit_auto_prefix| 218 | - Add |:ParteditEnd| command. 219 | - Change the argument of |:Partedit|. 220 | 221 | 1.0 2011-11-12 222 | - Initial version. 223 | 224 | 225 | ============================================================================== 226 | vim:tw=78:fo=tcq2mM:ts=8:ft=help:norl 227 | -------------------------------------------------------------------------------- /plugin/partedit.vim: -------------------------------------------------------------------------------- 1 | " Edits part of buffer by another buffer. 2 | " Version: 1.2 3 | " Author : thinca 4 | " License: zlib License 5 | 6 | if exists('g:loaded_partedit') 7 | finish 8 | endif 9 | let g:loaded_partedit = 1 10 | 11 | let s:save_cpo = &cpo 12 | set cpo&vim 13 | 14 | command! -nargs=? -range -complete=customlist,partedit#complete Partedit 15 | \ call partedit#command(, , ) 16 | 17 | let &cpo = s:save_cpo 18 | unlet s:save_cpo 19 | --------------------------------------------------------------------------------