-
Notifications
You must be signed in to change notification settings - Fork 2
/
TextTransform.txt
236 lines (196 loc) · 9.53 KB
/
TextTransform.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
*TextTransform.txt* Create text transformation mappings and commands.
TEXT TRANSFORM by Ingo Karkat
*TextTransform.vim*
description |TextTransform-description|
usage |TextTransform-usage|
installation |TextTransform-installation|
integration |TextTransform-integration|
limitations |TextTransform-limitations|
known problems |TextTransform-known-problems|
todo |TextTransform-todo|
history |TextTransform-history|
==============================================================================
DESCRIPTION *TextTransform-description*
This plugin allows you to build your own text transformations. You only supply
the transformation algorithm in the form of a Vim function that takes a string
and returns the transformed text (think |substitute()|), and TextTransform
will create all appropriate mappings and / or commands with a single call!
Do you often perform the same |:substitute| commands over and over again? You
may be able to save yourself a lot of typing by creating custom commands and
mappings for it. Because the mappings (like built-in Vim commands such as |gU|
or |g?|) are applicable to text moved over by {motion}, entire lines, and the
visual selection, you'll also have way more flexibility and places where you
can apply them (compared to the line-based range of :substitute).
RELATED WORKS *
- Idea, design and implementation are based on Tim Pope's unimpaired.vim
plugin (vimscript #1590). It implements XML, URL and C String encoding
mappings, but isn't extensible with other algorithms.
The TextTransform plugin enhances unimpaired's transformation function with
handling of text objects and a list of selection fallbacks, and allows to
not only create mappings, but also transformation commands.
==============================================================================
USAGE *TextTransform-usage*
*TextTransform#MakeMappings()*
TextTransform#MakeMappings( {mapArgs}, {key}, {algorithm} [, {selectionModes}] )
Create normal and visual mode mappings that apply
{algorithm} to the text covered by {motion}, [count]
line(s), and the visual selection.
When {key} is <Leader>xy, the following mappings will
be created:
- <Leader>xy{motion} applies to moved-over text
- <Leader>xyy applies to entire current line
- {Visual}<Leader>xy applies to visual selection
For the linewise normal mode mapping, the last
character of {key} is doubled, as is customary in Vim.
When {key} is empty, only <Plug> mappings are created;
mappings are also skipped when there are existing
mappings to the <Plug> mappings. When {algorithm} is
"MyTransform", the following <Plug> mappings are
generated: >
nmap <Plug>TextTMyTransformOperator
nmap <Plug>TextTMyTransformLine
vmap <Plug>TextTMyTransformVisual
< Use this to selectively override or disable individual
mappings.
|:map-arguments| can be passed in {mapArgs}, e.g.
"<buffer>" to make the generated mappings
buffer-local.
*TextTransform-algorithm*
{algorithm} is the name of a function: "MyTransform",
or a |Funcref|: function("MyTransform"). This function
must take one string argument and return a string. >
function MyTransform( text )
return '[' . toupper(a:text) . ']'
endfunction
< When the text that the mapping applies to spans more
than one line, {algorithm} is invoked only once with
the entire, newline-delimited text. You need to
consider that when using regular expression atoms like
|^| and |$|.
The function can |:throw| an exception to signal an
error. When the original text is returned,
TextTransform will print an error that nothing was
transformed. Do this when the transformation is not
applicable.
By default, the <Leader>xyy mapping will be applied to
the entire line. For some transformations, a different
default scope may make more sense, like the text
between quotes. After all, the <Leader>xyy mapping is
often faster than <Leader>xy{motion} or first doing a
visual selection, and is easiest to commit to muscle
memory, so it should "do what I mean".
*TextTransform-selectionModes*
The optional {selectionModes} argument is a single
text object (such as "aw"), motion (e.g. "$"),
|Funcref| (for a custom selection), or the string
"lines", which represents the default behavior.
If you pass a list of these, TextTransform tries each
selectionMode, one after the other, until one captures
non-empty text. For example, the passed list ['i"',
"i'", "lines"] will cause TextTransform to first try
to capture the text inside double quotes, then fall
back to text inside single quotes when the first one
doesn't yield any text. Finally, the "lines" will
transform the entire line if the single quote capture
failed, too.
A custom function should create a visual selection and
return a non-zero value if the selection can be made.
(Otherwise, the next selectionMode in the list is
tried.) Here's a senseless example which selects
[count] characters to the right of the cursor: >
function! MySelect()
execute 'normal! lv' . v:count1 . "l\<Esc>"
return 1
endfunction
<
*TextTransform#MakeCommand()*
TextTransform#MakeCommand( {commandOptions}, {commandName}, {algorithm} [, {options}] )
Create a custom command {commandName} that takes a
range (defaulting to the current line), and applies
{algorithm} to the line(s).
|:command| attributes can be passed in
{commandOptions}. For example, pass "-range=%" to make
the command apply to the entire buffer when no range
is specified.
{algorithm} is the name of a function or a |Funcref|,
cp. |Transform-algorithm|.
The optional {options} dictionary can contain the
following keys:
isProcessEntireText Flag whether all lines are passed as one
newline-delimited string to {algorithm}, like mappings
from |TextTransform#MakeMappings()| do. Off by
default, so that each line is passed to {algorithm}
individually (without the newline). This allows for a
more efficient transformation. You need to enable this
if {algorithm} transforms the newline, adds or removes
lines.
*TextTransform#MakeSelectionCommand()*
TextTransform#MakeSelectionCommand( {commandOptions}, {commandName}, {algorithm}, {selectionModes} )
Create a custom command {commandName} that applies
{algorithm} on the |TextTransform-selectionModes|
specified by {selectionModes}, or the current visual
selection (when invoked from visual mode).
This is useful for algorithms that do not make sense
on entire lines. It's the command-variant of the
line-based mapping created by
|TextTransform#MakeMappings()|. For seldomly used
transformations, a command may have advantages over a
mapping: It doesn't take up precious mapping keys and
is more explorable via command-line completion.
Rest of the arguments as with |TextTransform#MakeCommand()|.
EXAMPLE *TextTransform-example*
Here's a stupid transformation function that replaces all alphabetic
characters with "X": >
function! BlankOut( text )
return substitute(a:text, '\a', 'X', 'g')
endfunction
With this, this single call: >
call TextTransform#MakeMappings('', '<Leader>x', 'BlankOut')
creates this set of mappings:
<Leader>x{motion} transforms the text covered by {motion}
<Leader>xx transforms [count] line(s)
{Visual}<Leader>x transforms the visual selection
You can set up a command for this transformation just as easily: >
call TextTransform#MakeCommand('', 'TextBlankOut', 'BlankOut')
so you can blank out the next three lines via >
:.,.+2TextBlankOut
<
==============================================================================
INSTALLATION *TextTransform-installation*
This script is packaged as a |vimball|. If you have the "gunzip" decompressor
in your PATH, simply edit the *.vba.gz package in Vim; otherwise, decompress
the archive first, e.g. using WinZip. Inside Vim, install by sourcing the
vimball or via the |:UseVimball| command. >
vim TextTransform.vba.gz
:so %
To uninstall, use the |:RmVimball| command.
DEPENDENCIES *TextTransform-dependencies*
- Requires Vim 7.0 or higher.
- repeat.vim (vimscript #2136) plugin (optional)
- visualrepeat.vim (vimscript #3848) plugin (optional)
==============================================================================
INTEGRATION *TextTransform-integration*
==============================================================================
LIMITATIONS *TextTransform-limitations*
KNOWN PROBLEMS *TextTransform-known-problems*
TODO *TextTransform-todo*
IDEAS *TextTransform-ideas*
==============================================================================
HISTORY *TextTransform-history*
1.02 28-Jul-2012
Avoid "E706: Variable type mismatch" when TextTransform#Arbitrary#Expression()
is used with both Funcref- and String-type algorithms.
1.01 05-Apr-2012
In mappings and selection commands, place the cursor at the beginning of the
transformed text, to be consistent with built-in transformation commands like
gU, and because it makes much more sense.
1.00 05-Apr-2012
First published version.
0.01 07-Mar-2011
Started development.
==============================================================================
Copyright: (C) 2011-2012 Ingo Karkat
The VIM LICENSE applies to this script; see |copyright|.
Maintainer: Ingo Karkat <ingo@karkat.de>
==============================================================================
vim:tw=78:ts=8:ft=help:norl: