Vim Tips Wiki
No edit summary
 
(Remove html character entities)
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
{{review}}
 
{{review}}
  +
{{TipImported
{{Tip
 
 
|id=786
 
|id=786
  +
|previous=785
|title=Character-set translation
 
  +
|next=787
|created=September 9, 2004 16:10
+
|created=September 9, 2004
 
|complexity=intermediate
 
|complexity=intermediate
 
|author=Breadman
 
|author=Breadman
 
|version=5.7
 
|version=5.7
 
|rating=0/0
 
|rating=0/0
  +
|category1=
|text=
 
  +
|category2=
Benji Fisher's foo.vim ([/scripts/script.php?script_id=72 vimscript #72]) contains a Transform command that I initially thought would be very helpful: I tend to swap double and single quotation marks around, as well as other pairs of characters. Unfortunately, the original command fails in this case. Below is an updated version which is probably slower, but more powerful, as well as a map for my favorite way to use it.
 
 
}}
  +
I tend to swap double and single quotation marks around, as well as other pairs of characters. There is a transform command that I initially thought would be very helpful in {{script|id=72}}.
   
 
Unfortunately, the original command fails in this case. Below is an updated version which is probably slower, but more powerful, as well as a map for my favorite way to use it.
   
 
Also included is a character-switching function I developed in the process, but ended up including inline for efficiency. It turns out that directly assigning to a character in a string (let string[i] = a:new[pos]) is illegal, probably because the rhs can include more than one byte. StrSwitchPos() takes care of that, but doesn't enforce a single-byte replacement.
   
  +
<pre>
Also included is a character-switching function I developed in the process, but ended up including inline for efficiency. It turns out that directly assigning to a character in a string (let string[i] = a:new[pos]) is illegal, probably because the rhs can include more than one byte. StrSwitchPos() takes care of that, but doesn't enforce a single-byte replacement.
 
 
" Translate character sets, either in the current line, on a range, or in a string
 
" Note that in this version, unmatched characters in old are deleted
 
command! -nargs=* -range Transform <line1>,<line2> call Transform(<f-args>)
 
function! Transform(old, new, ...)
 
let string = a:0 ? a:1 : getline('.')
 
let i = strlen(string)
 
while i > 0
 
let i = i - 1
 
let pos = stridx(a:old, string[i])
 
if pos > -1
 
let string = strpart(string, 0, i) . a:new[pos] . strpart(string, i + 1)
  +
endif
  +
endwhile
 
if a:0
 
return string
  +
else
 
call setline('.', string)
  +
endif
 
endfunction
 
noremap <silent> "" :Transform "' '"<CR>
   
 
" Spin-off from the above: switch a single character specified by index
 
fun! StrSwitchPos(string, pos, char)
 
return strpart(a:string, 0, a:pos) . a:char . strpart(a:string, a:pos + 1)
 
endfun
  +
</pre>
   
 
==Comments==
 
 
 
" Translate character sets, either in the current line, on a range, or in a string
 
 
" Note that in this version, unmatched characters in old are deleted
 
 
command! -nargs=* -range Transform &lt;line1&gt;,&lt;line2&gt; call Transform(&lt;f-args&gt;)
 
 
function! Transform(old, new, ...)
 
 
let string = a:0 ? a:1 : getline('.')
 
 
 
 
let i = strlen(string)
 
 
while i &gt; 0
 
 
let i = i - 1
 
 
let pos = stridx(a:old, string[i])
 
 
if pos &gt; -1
 
 
let string = strpart(string, 0, i) . a:new[pos] . strpart(string, i + 1)
 
 
endif
 
 
endwhile
 
 
 
 
if a:0
 
 
return string
 
 
else
 
 
call setline('.', string)
 
 
endif
 
 
endfunction
 
 
 
 
noremap &lt;silent&gt; "" :Transform "' '"&lt;CR&gt;
 
 
 
 
" Spin-off from the above: switch a single character specified by index
 
 
fun! StrSwitchPos(string, pos, char)
 
 
return strpart(a:string, 0, a:pos) . a:char . strpart(a:string, a:pos + 1)
 
 
endfun
 
 
 
}}
 
 
== Comments ==
 
<!-- parsed by vimtips.py in 0.546862 seconds-->
 

Latest revision as of 09:24, 29 September 2008

Tip 786 Printable Monobook Previous Next

created September 9, 2004 · complexity intermediate · author Breadman · version 5.7


I tend to swap double and single quotation marks around, as well as other pairs of characters. There is a transform command that I initially thought would be very helpful in script#72.

Unfortunately, the original command fails in this case. Below is an updated version which is probably slower, but more powerful, as well as a map for my favorite way to use it.

Also included is a character-switching function I developed in the process, but ended up including inline for efficiency. It turns out that directly assigning to a character in a string (let string[i] = a:new[pos]) is illegal, probably because the rhs can include more than one byte. StrSwitchPos() takes care of that, but doesn't enforce a single-byte replacement.

" Translate character sets, either in the current line, on a range, or in a string
" Note that in this version, unmatched characters in old are deleted
command! -nargs=* -range Transform <line1>,<line2> call Transform(<f-args>)
function! Transform(old, new, ...)
  let string = a:0 ? a:1 : getline('.')
  let i = strlen(string)
  while i > 0
    let i = i - 1
    let pos = stridx(a:old, string[i])
    if pos > -1
      let string = strpart(string, 0, i) . a:new[pos] . strpart(string, i + 1)
    endif
  endwhile
  if a:0
    return string
  else
    call setline('.', string)
  endif
endfunction
noremap <silent> "" :Transform "' '"<CR>

" Spin-off from the above: switch a single character specified by index
fun! StrSwitchPos(string, pos, char)
  return strpart(a:string, 0, a:pos) . a:char . strpart(a:string, a:pos + 1)
endfun

Comments[]