mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-04-25 19:15:45 +02:00
Changes and additions to support true VIM searching and replacing
This commit is contained in:
parent
d09cc6b053
commit
4dc6a2ab72
docs
license
src/com/maddyhome/idea/vim
@ -6,6 +6,7 @@ Redone Commands
|
|||||||
- / and ? and all their variants are now supported properly, including offsets.
|
- / and ? and all their variants are now supported properly, including offsets.
|
||||||
- n and N are now supported properly
|
- n and N are now supported properly
|
||||||
- Ex command ranges now fully support searches
|
- Ex command ranges now fully support searches
|
||||||
|
- :substitute command now fully supports all Vim style search and replaces
|
||||||
|
|
||||||
New Commands
|
New Commands
|
||||||
- Added support for :set. Only a small number of options are supported.
|
- Added support for :set. Only a small number of options are supported.
|
||||||
|
@ -3,5 +3,6 @@
|
|||||||
VIM Emulator plugin for IntelliJ IDEA. See the enclosed README file in the
|
VIM Emulator plugin for IntelliJ IDEA. See the enclosed README file in the
|
||||||
binary distribution for installation instructions. See docs/vim/index.txt for
|
binary distribution for installation instructions. See docs/vim/index.txt for
|
||||||
a complete list of supported VIM commands. This release has been tested with
|
a complete list of supported VIM commands. This release has been tested with
|
||||||
IDEA 3.0.2 (build #695) and 3.0.3 (build #698) but may work with other 3.0
|
IDEA 3.0.2 (build #695), 3.0.3 (build #698), and 3.0.4 (build #701) but may
|
||||||
releases.
|
work with other 3.0 releases. Limited testing indicates the plugin works just
|
||||||
|
fine under Aurora.
|
@ -1,504 +0,0 @@
|
|||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
Version 2.1, February 1999
|
|
||||||
|
|
||||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
|
||||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
[This is the first released version of the Lesser GPL. It also counts
|
|
||||||
as the successor of the GNU Library Public License, version 2, hence
|
|
||||||
the version number 2.1.]
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
Licenses are intended to guarantee your freedom to share and change
|
|
||||||
free software--to make sure the software is free for all its users.
|
|
||||||
|
|
||||||
This license, the Lesser General Public License, applies to some
|
|
||||||
specially designated software packages--typically libraries--of the
|
|
||||||
Free Software Foundation and other authors who decide to use it. You
|
|
||||||
can use it too, but we suggest you first think carefully about whether
|
|
||||||
this license or the ordinary General Public License is the better
|
|
||||||
strategy to use in any particular case, based on the explanations below.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom of use,
|
|
||||||
not price. Our General Public Licenses are designed to make sure that
|
|
||||||
you have the freedom to distribute copies of free software (and charge
|
|
||||||
for this service if you wish); that you receive source code or can get
|
|
||||||
it if you want it; that you can change the software and use pieces of
|
|
||||||
it in new free programs; and that you are informed that you can do
|
|
||||||
these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
distributors to deny you these rights or to ask you to surrender these
|
|
||||||
rights. These restrictions translate to certain responsibilities for
|
|
||||||
you if you distribute copies of the library or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of the library, whether gratis
|
|
||||||
or for a fee, you must give the recipients all the rights that we gave
|
|
||||||
you. You must make sure that they, too, receive or can get the source
|
|
||||||
code. If you link other code with the library, you must provide
|
|
||||||
complete object files to the recipients, so that they can relink them
|
|
||||||
with the library after making changes to the library and recompiling
|
|
||||||
it. And you must show them these terms so they know their rights.
|
|
||||||
|
|
||||||
We protect your rights with a two-step method: (1) we copyright the
|
|
||||||
library, and (2) we offer you this license, which gives you legal
|
|
||||||
permission to copy, distribute and/or modify the library.
|
|
||||||
|
|
||||||
To protect each distributor, we want to make it very clear that
|
|
||||||
there is no warranty for the free library. Also, if the library is
|
|
||||||
modified by someone else and passed on, the recipients should know
|
|
||||||
that what they have is not the original version, so that the original
|
|
||||||
author's reputation will not be affected by problems that might be
|
|
||||||
introduced by others.
|
|
||||||
|
|
||||||
Finally, software patents pose a constant threat to the existence of
|
|
||||||
any free program. We wish to make sure that a company cannot
|
|
||||||
effectively restrict the users of a free program by obtaining a
|
|
||||||
restrictive license from a patent holder. Therefore, we insist that
|
|
||||||
any patent license obtained for a version of the library must be
|
|
||||||
consistent with the full freedom of use specified in this license.
|
|
||||||
|
|
||||||
Most GNU software, including some libraries, is covered by the
|
|
||||||
ordinary GNU General Public License. This license, the GNU Lesser
|
|
||||||
General Public License, applies to certain designated libraries, and
|
|
||||||
is quite different from the ordinary General Public License. We use
|
|
||||||
this license for certain libraries in order to permit linking those
|
|
||||||
libraries into non-free programs.
|
|
||||||
|
|
||||||
When a program is linked with a library, whether statically or using
|
|
||||||
a shared library, the combination of the two is legally speaking a
|
|
||||||
combined work, a derivative of the original library. The ordinary
|
|
||||||
General Public License therefore permits such linking only if the
|
|
||||||
entire combination fits its criteria of freedom. The Lesser General
|
|
||||||
Public License permits more lax criteria for linking other code with
|
|
||||||
the library.
|
|
||||||
|
|
||||||
We call this license the "Lesser" General Public License because it
|
|
||||||
does Less to protect the user's freedom than the ordinary General
|
|
||||||
Public License. It also provides other free software developers Less
|
|
||||||
of an advantage over competing non-free programs. These disadvantages
|
|
||||||
are the reason we use the ordinary General Public License for many
|
|
||||||
libraries. However, the Lesser license provides advantages in certain
|
|
||||||
special circumstances.
|
|
||||||
|
|
||||||
For example, on rare occasions, there may be a special need to
|
|
||||||
encourage the widest possible use of a certain library, so that it becomes
|
|
||||||
a de-facto standard. To achieve this, non-free programs must be
|
|
||||||
allowed to use the library. A more frequent case is that a free
|
|
||||||
library does the same job as widely used non-free libraries. In this
|
|
||||||
case, there is little to gain by limiting the free library to free
|
|
||||||
software only, so we use the Lesser General Public License.
|
|
||||||
|
|
||||||
In other cases, permission to use a particular library in non-free
|
|
||||||
programs enables a greater number of people to use a large body of
|
|
||||||
free software. For example, permission to use the GNU C Library in
|
|
||||||
non-free programs enables many more people to use the whole GNU
|
|
||||||
operating system, as well as its variant, the GNU/Linux operating
|
|
||||||
system.
|
|
||||||
|
|
||||||
Although the Lesser General Public License is Less protective of the
|
|
||||||
users' freedom, it does ensure that the user of a program that is
|
|
||||||
linked with the Library has the freedom and the wherewithal to run
|
|
||||||
that program using a modified version of the Library.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow. Pay close attention to the difference between a
|
|
||||||
"work based on the library" and a "work that uses the library". The
|
|
||||||
former contains code derived from the library, whereas the latter must
|
|
||||||
be combined with the library in order to run.
|
|
||||||
|
|
||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License Agreement applies to any software library or other
|
|
||||||
program which contains a notice placed by the copyright holder or
|
|
||||||
other authorized party saying it may be distributed under the terms of
|
|
||||||
this Lesser General Public License (also called "this License").
|
|
||||||
Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
A "library" means a collection of software functions and/or data
|
|
||||||
prepared so as to be conveniently linked with application programs
|
|
||||||
(which use some of those functions and data) to form executables.
|
|
||||||
|
|
||||||
The "Library", below, refers to any such software library or work
|
|
||||||
which has been distributed under these terms. A "work based on the
|
|
||||||
Library" means either the Library or any derivative work under
|
|
||||||
copyright law: that is to say, a work containing the Library or a
|
|
||||||
portion of it, either verbatim or with modifications and/or translated
|
|
||||||
straightforwardly into another language. (Hereinafter, translation is
|
|
||||||
included without limitation in the term "modification".)
|
|
||||||
|
|
||||||
"Source code" for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For a library, complete source code means
|
|
||||||
all the source code for all modules it contains, plus any associated
|
|
||||||
interface definition files, plus the scripts used to control compilation
|
|
||||||
and installation of the library.
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running a program using the Library is not restricted, and output from
|
|
||||||
such a program is covered only if its contents constitute a work based
|
|
||||||
on the Library (independent of the use of the Library in a tool for
|
|
||||||
writing it). Whether that is true depends on what the Library does
|
|
||||||
and what the program that uses the Library does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Library's
|
|
||||||
complete source code as you receive it, in any medium, provided that
|
|
||||||
you conspicuously and appropriately publish on each copy an
|
|
||||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
|
||||||
all the notices that refer to this License and to the absence of any
|
|
||||||
warranty; and distribute a copy of this License along with the
|
|
||||||
Library.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy,
|
|
||||||
and you may at your option offer warranty protection in exchange for a
|
|
||||||
fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Library or any portion
|
|
||||||
of it, thus forming a work based on the Library, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The modified work must itself be a software library.
|
|
||||||
|
|
||||||
b) You must cause the files modified to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
c) You must cause the whole of the work to be licensed at no
|
|
||||||
charge to all third parties under the terms of this License.
|
|
||||||
|
|
||||||
d) If a facility in the modified Library refers to a function or a
|
|
||||||
table of data to be supplied by an application program that uses
|
|
||||||
the facility, other than as an argument passed when the facility
|
|
||||||
is invoked, then you must make a good faith effort to ensure that,
|
|
||||||
in the event an application does not supply such function or
|
|
||||||
table, the facility still operates, and performs whatever part of
|
|
||||||
its purpose remains meaningful.
|
|
||||||
|
|
||||||
(For example, a function in a library to compute square roots has
|
|
||||||
a purpose that is entirely well-defined independent of the
|
|
||||||
application. Therefore, Subsection 2d requires that any
|
|
||||||
application-supplied function or table used by this function must
|
|
||||||
be optional: if the application does not supply it, the square
|
|
||||||
root function must still compute square roots.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Library,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Library, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote
|
|
||||||
it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Library.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Library
|
|
||||||
with the Library (or with a work based on the Library) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
|
||||||
License instead of this License to a given copy of the Library. To do
|
|
||||||
this, you must alter all the notices that refer to this License, so
|
|
||||||
that they refer to the ordinary GNU General Public License, version 2,
|
|
||||||
instead of to this License. (If a newer version than version 2 of the
|
|
||||||
ordinary GNU General Public License has appeared, then you can specify
|
|
||||||
that version instead if you wish.) Do not make any other change in
|
|
||||||
these notices.
|
|
||||||
|
|
||||||
Once this change is made in a given copy, it is irreversible for
|
|
||||||
that copy, so the ordinary GNU General Public License applies to all
|
|
||||||
subsequent copies and derivative works made from that copy.
|
|
||||||
|
|
||||||
This option is useful when you wish to copy part of the code of
|
|
||||||
the Library into a program that is not a library.
|
|
||||||
|
|
||||||
4. You may copy and distribute the Library (or a portion or
|
|
||||||
derivative of it, under Section 2) in object code or executable form
|
|
||||||
under the terms of Sections 1 and 2 above provided that you accompany
|
|
||||||
it with the complete corresponding machine-readable source code, which
|
|
||||||
must be distributed under the terms of Sections 1 and 2 above on a
|
|
||||||
medium customarily used for software interchange.
|
|
||||||
|
|
||||||
If distribution of object code is made by offering access to copy
|
|
||||||
from a designated place, then offering equivalent access to copy the
|
|
||||||
source code from the same place satisfies the requirement to
|
|
||||||
distribute the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
5. A program that contains no derivative of any portion of the
|
|
||||||
Library, but is designed to work with the Library by being compiled or
|
|
||||||
linked with it, is called a "work that uses the Library". Such a
|
|
||||||
work, in isolation, is not a derivative work of the Library, and
|
|
||||||
therefore falls outside the scope of this License.
|
|
||||||
|
|
||||||
However, linking a "work that uses the Library" with the Library
|
|
||||||
creates an executable that is a derivative of the Library (because it
|
|
||||||
contains portions of the Library), rather than a "work that uses the
|
|
||||||
library". The executable is therefore covered by this License.
|
|
||||||
Section 6 states terms for distribution of such executables.
|
|
||||||
|
|
||||||
When a "work that uses the Library" uses material from a header file
|
|
||||||
that is part of the Library, the object code for the work may be a
|
|
||||||
derivative work of the Library even though the source code is not.
|
|
||||||
Whether this is true is especially significant if the work can be
|
|
||||||
linked without the Library, or if the work is itself a library. The
|
|
||||||
threshold for this to be true is not precisely defined by law.
|
|
||||||
|
|
||||||
If such an object file uses only numerical parameters, data
|
|
||||||
structure layouts and accessors, and small macros and small inline
|
|
||||||
functions (ten lines or less in length), then the use of the object
|
|
||||||
file is unrestricted, regardless of whether it is legally a derivative
|
|
||||||
work. (Executables containing this object code plus portions of the
|
|
||||||
Library will still fall under Section 6.)
|
|
||||||
|
|
||||||
Otherwise, if the work is a derivative of the Library, you may
|
|
||||||
distribute the object code for the work under the terms of Section 6.
|
|
||||||
Any executables containing that work also fall under Section 6,
|
|
||||||
whether or not they are linked directly with the Library itself.
|
|
||||||
|
|
||||||
6. As an exception to the Sections above, you may also combine or
|
|
||||||
link a "work that uses the Library" with the Library to produce a
|
|
||||||
work containing portions of the Library, and distribute that work
|
|
||||||
under terms of your choice, provided that the terms permit
|
|
||||||
modification of the work for the customer's own use and reverse
|
|
||||||
engineering for debugging such modifications.
|
|
||||||
|
|
||||||
You must give prominent notice with each copy of the work that the
|
|
||||||
Library is used in it and that the Library and its use are covered by
|
|
||||||
this License. You must supply a copy of this License. If the work
|
|
||||||
during execution displays copyright notices, you must include the
|
|
||||||
copyright notice for the Library among them, as well as a reference
|
|
||||||
directing the user to the copy of this License. Also, you must do one
|
|
||||||
of these things:
|
|
||||||
|
|
||||||
a) Accompany the work with the complete corresponding
|
|
||||||
machine-readable source code for the Library including whatever
|
|
||||||
changes were used in the work (which must be distributed under
|
|
||||||
Sections 1 and 2 above); and, if the work is an executable linked
|
|
||||||
with the Library, with the complete machine-readable "work that
|
|
||||||
uses the Library", as object code and/or source code, so that the
|
|
||||||
user can modify the Library and then relink to produce a modified
|
|
||||||
executable containing the modified Library. (It is understood
|
|
||||||
that the user who changes the contents of definitions files in the
|
|
||||||
Library will not necessarily be able to recompile the application
|
|
||||||
to use the modified definitions.)
|
|
||||||
|
|
||||||
b) Use a suitable shared library mechanism for linking with the
|
|
||||||
Library. A suitable mechanism is one that (1) uses at run time a
|
|
||||||
copy of the library already present on the user's computer system,
|
|
||||||
rather than copying library functions into the executable, and (2)
|
|
||||||
will operate properly with a modified version of the library, if
|
|
||||||
the user installs one, as long as the modified version is
|
|
||||||
interface-compatible with the version that the work was made with.
|
|
||||||
|
|
||||||
c) Accompany the work with a written offer, valid for at
|
|
||||||
least three years, to give the same user the materials
|
|
||||||
specified in Subsection 6a, above, for a charge no more
|
|
||||||
than the cost of performing this distribution.
|
|
||||||
|
|
||||||
d) If distribution of the work is made by offering access to copy
|
|
||||||
from a designated place, offer equivalent access to copy the above
|
|
||||||
specified materials from the same place.
|
|
||||||
|
|
||||||
e) Verify that the user has already received a copy of these
|
|
||||||
materials or that you have already sent this user a copy.
|
|
||||||
|
|
||||||
For an executable, the required form of the "work that uses the
|
|
||||||
Library" must include any data and utility programs needed for
|
|
||||||
reproducing the executable from it. However, as a special exception,
|
|
||||||
the materials to be distributed need not include anything that is
|
|
||||||
normally distributed (in either source or binary form) with the major
|
|
||||||
components (compiler, kernel, and so on) of the operating system on
|
|
||||||
which the executable runs, unless that component itself accompanies
|
|
||||||
the executable.
|
|
||||||
|
|
||||||
It may happen that this requirement contradicts the license
|
|
||||||
restrictions of other proprietary libraries that do not normally
|
|
||||||
accompany the operating system. Such a contradiction means you cannot
|
|
||||||
use both them and the Library together in an executable that you
|
|
||||||
distribute.
|
|
||||||
|
|
||||||
7. You may place library facilities that are a work based on the
|
|
||||||
Library side-by-side in a single library together with other library
|
|
||||||
facilities not covered by this License, and distribute such a combined
|
|
||||||
library, provided that the separate distribution of the work based on
|
|
||||||
the Library and of the other library facilities is otherwise
|
|
||||||
permitted, and provided that you do these two things:
|
|
||||||
|
|
||||||
a) Accompany the combined library with a copy of the same work
|
|
||||||
based on the Library, uncombined with any other library
|
|
||||||
facilities. This must be distributed under the terms of the
|
|
||||||
Sections above.
|
|
||||||
|
|
||||||
b) Give prominent notice with the combined library of the fact
|
|
||||||
that part of it is a work based on the Library, and explaining
|
|
||||||
where to find the accompanying uncombined form of the same work.
|
|
||||||
|
|
||||||
8. You may not copy, modify, sublicense, link with, or distribute
|
|
||||||
the Library except as expressly provided under this License. Any
|
|
||||||
attempt otherwise to copy, modify, sublicense, link with, or
|
|
||||||
distribute the Library is void, and will automatically terminate your
|
|
||||||
rights under this License. However, parties who have received copies,
|
|
||||||
or rights, from you under this License will not have their licenses
|
|
||||||
terminated so long as such parties remain in full compliance.
|
|
||||||
|
|
||||||
9. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Library or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Library (or any work based on the
|
|
||||||
Library), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Library or works based on it.
|
|
||||||
|
|
||||||
10. Each time you redistribute the Library (or any work based on the
|
|
||||||
Library), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute, link with or modify the Library
|
|
||||||
subject to these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties with
|
|
||||||
this License.
|
|
||||||
|
|
||||||
11. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Library at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Library by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Library.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under any
|
|
||||||
particular circumstance, the balance of the section is intended to apply,
|
|
||||||
and the section as a whole is intended to apply in other circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
12. If the distribution and/or use of the Library is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Library under this License may add
|
|
||||||
an explicit geographical distribution limitation excluding those countries,
|
|
||||||
so that distribution is permitted only in or among countries not thus
|
|
||||||
excluded. In such case, this License incorporates the limitation as if
|
|
||||||
written in the body of this License.
|
|
||||||
|
|
||||||
13. The Free Software Foundation may publish revised and/or new
|
|
||||||
versions of the Lesser General Public License from time to time.
|
|
||||||
Such new versions will be similar in spirit to the present version,
|
|
||||||
but may differ in detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Library
|
|
||||||
specifies a version number of this License which applies to it and
|
|
||||||
"any later version", you have the option of following the terms and
|
|
||||||
conditions either of that version or of any later version published by
|
|
||||||
the Free Software Foundation. If the Library does not specify a
|
|
||||||
license version number, you may choose any version ever published by
|
|
||||||
the Free Software Foundation.
|
|
||||||
|
|
||||||
14. If you wish to incorporate parts of the Library into other free
|
|
||||||
programs whose distribution conditions are incompatible with these,
|
|
||||||
write to the author to ask for permission. For software which is
|
|
||||||
copyrighted by the Free Software Foundation, write to the Free
|
|
||||||
Software Foundation; we sometimes make exceptions for this. Our
|
|
||||||
decision will be guided by the two goals of preserving the free status
|
|
||||||
of all derivatives of our free software and of promoting the sharing
|
|
||||||
and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
|
||||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
|
||||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
|
||||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
|
||||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
|
||||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
|
||||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
|
||||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
|
||||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
|
||||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
|
||||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
|
||||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
|
||||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
|
||||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
|
||||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|
||||||
DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Libraries
|
|
||||||
|
|
||||||
If you develop a new library, and you want it to be of the greatest
|
|
||||||
possible use to the public, we recommend making it free software that
|
|
||||||
everyone can redistribute and change. You can do so by permitting
|
|
||||||
redistribution under these terms (or, alternatively, under the terms of the
|
|
||||||
ordinary General Public License).
|
|
||||||
|
|
||||||
To apply these terms, attach the following notices to the library. It is
|
|
||||||
safest to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least the
|
|
||||||
"copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the library's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
|
||||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1990
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
That's all there is to it!
|
|
||||||
|
|
||||||
|
|
@ -37,6 +37,7 @@ public class QuitHandler extends CommandHandler
|
|||||||
|
|
||||||
public boolean execute(Editor editor, DataContext context, ExCommand cmd)
|
public boolean execute(Editor editor, DataContext context, ExCommand cmd)
|
||||||
{
|
{
|
||||||
|
// TODO - redo this properly
|
||||||
CommandGroups.getInstance().getFile().saveFiles(context);
|
CommandGroups.getInstance().getFile().saveFiles(context);
|
||||||
CommandGroups.getInstance().getFile().closeFile(editor, context);
|
CommandGroups.getInstance().getFile().closeFile(editor, context);
|
||||||
if (cmd.getArgument().equals("!"))
|
if (cmd.getArgument().equals("!"))
|
||||||
|
@ -20,17 +20,13 @@ package com.maddyhome.idea.vim.ex.handler;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext;
|
import com.intellij.openapi.actionSystem.DataContext;
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
|
||||||
import com.intellij.openapi.editor.Editor;
|
import com.intellij.openapi.editor.Editor;
|
||||||
import com.intellij.openapi.util.TextRange;
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler;
|
import com.maddyhome.idea.vim.ex.CommandHandler;
|
||||||
import com.maddyhome.idea.vim.ex.CommandName;
|
import com.maddyhome.idea.vim.ex.CommandName;
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand;
|
import com.maddyhome.idea.vim.ex.ExCommand;
|
||||||
import com.maddyhome.idea.vim.ex.ExException;
|
import com.maddyhome.idea.vim.ex.ExException;
|
||||||
|
import com.maddyhome.idea.vim.ex.LineRange;
|
||||||
import com.maddyhome.idea.vim.group.CommandGroups;
|
import com.maddyhome.idea.vim.group.CommandGroups;
|
||||||
import com.maddyhome.idea.vim.group.SearchGroup;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -48,6 +44,7 @@ public class SubstituteHandler extends CommandHandler
|
|||||||
|
|
||||||
public boolean execute(Editor editor, DataContext context, ExCommand cmd) throws ExException
|
public boolean execute(Editor editor, DataContext context, ExCommand cmd) throws ExException
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
String arg = cmd.getArgument();
|
String arg = cmd.getArgument();
|
||||||
logger.debug("arg="+arg);
|
logger.debug("arg="+arg);
|
||||||
String pattern = "";
|
String pattern = "";
|
||||||
@ -120,9 +117,10 @@ public class SubstituteHandler extends CommandHandler
|
|||||||
{
|
{
|
||||||
sflags |= SearchGroup.REUSE;
|
sflags |= SearchGroup.REUSE;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return CommandGroups.getInstance().getSearch().searchAndReplace(editor, context, range, pattern, replace, sflags);
|
LineRange range = cmd.getLineRange(editor, context, false);
|
||||||
|
return CommandGroups.getInstance().getSearch().searchAndReplace(editor, context, range, cmd.getCommand(),
|
||||||
|
cmd.getArgument());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Logger logger = Logger.getInstance(SubstituteHandler.class.getName());
|
|
||||||
}
|
}
|
||||||
|
@ -24,20 +24,20 @@ import com.intellij.openapi.diagnostic.Logger;
|
|||||||
import com.intellij.openapi.editor.Editor;
|
import com.intellij.openapi.editor.Editor;
|
||||||
import com.intellij.openapi.editor.LogicalPosition;
|
import com.intellij.openapi.editor.LogicalPosition;
|
||||||
import com.intellij.openapi.editor.markup.HighlighterLayer;
|
import com.intellij.openapi.editor.markup.HighlighterLayer;
|
||||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
|
||||||
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
|
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
|
||||||
|
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||||
|
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||||
import com.intellij.openapi.util.TextRange;
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.maddyhome.idea.vim.command.Command;
|
import com.maddyhome.idea.vim.command.Command;
|
||||||
|
import com.maddyhome.idea.vim.ex.LineRange;
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper;
|
import com.maddyhome.idea.vim.helper.EditorHelper;
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper;
|
|
||||||
import com.maddyhome.idea.vim.helper.SearchHelper;
|
import com.maddyhome.idea.vim.helper.SearchHelper;
|
||||||
|
import com.maddyhome.idea.vim.helper.StringHelper;
|
||||||
import com.maddyhome.idea.vim.option.Options;
|
import com.maddyhome.idea.vim.option.Options;
|
||||||
import gnu.regexp.RE;
|
import com.maddyhome.idea.vim.regexp.CharHelper;
|
||||||
import gnu.regexp.REException;
|
import com.maddyhome.idea.vim.regexp.CharPointer;
|
||||||
import gnu.regexp.REMatch;
|
import com.maddyhome.idea.vim.regexp.CharacterClasses;
|
||||||
import gnu.regexp.RESyntax;
|
import com.maddyhome.idea.vim.regexp.RegExp;
|
||||||
import java.nio.CharBuffer;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.text.ParsePosition;
|
import java.text.ParsePosition;
|
||||||
@ -71,92 +71,285 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
return lastPattern;
|
return lastPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean searchAndReplace(Editor editor, DataContext context, TextRange range, String pattern, String replace,
|
public boolean searchAndReplace(Editor editor, DataContext context, LineRange range, String excmd, String exarg)
|
||||||
int flags)
|
|
||||||
{
|
{
|
||||||
boolean res = true;
|
boolean res = true;
|
||||||
|
|
||||||
if ((flags & KEEP_FLAGS) != 0)
|
CharPointer cmd = new CharPointer(new StringBuffer(exarg));
|
||||||
{
|
//sub_nsubs = 0;
|
||||||
flags |= lastFlags;
|
//sub_nlines = 0;
|
||||||
}
|
|
||||||
lastFlags = flags;
|
|
||||||
|
|
||||||
int pflags = RE.REG_MULTILINE;
|
int which_pat;
|
||||||
// If the user set the i flag or they didn't set the I flag but the ignorecase option is set, then ignore case
|
if (excmd.equals("~"))
|
||||||
if ((flags & IGNORE_CASE) != 0 || ((flags & NO_IGNORE_CASE) == 0 && shouldIgnoreCase(pattern, false)))
|
which_pat = RE_LAST; /* use last used regexp */
|
||||||
{
|
else
|
||||||
pflags |= RE.REG_ICASE;
|
which_pat = RE_SUBST; /* use last substitute regexp */
|
||||||
}
|
|
||||||
|
|
||||||
RE sp;
|
CharPointer pat = null;
|
||||||
if (pattern.length() == 0)
|
CharPointer sub = null;
|
||||||
|
char delimiter;
|
||||||
|
/* new pattern and substitution */
|
||||||
|
if (excmd.charAt(0) == 's' && !cmd.isNul() && !Character.isWhitespace(cmd.charAt()) &&
|
||||||
|
"0123456789cegriIp|\"".indexOf(cmd.charAt()) == -1)
|
||||||
{
|
{
|
||||||
if ((flags & REUSE) != 0)
|
/* don't accept alphanumeric for separator */
|
||||||
|
if (CharacterClasses.isAlpha(cmd.charAt()))
|
||||||
{
|
{
|
||||||
pattern = lastSearch;
|
// EMSG(_("E146: Regular expressions can't be delimited by letters")); TODO
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
/*
|
||||||
|
* undocumented vi feature:
|
||||||
|
* "\/sub/" and "\?sub?" use last used search pattern (almost like
|
||||||
|
* //sub/r). "\&sub&" use last substitute pattern (like //sub/).
|
||||||
|
*/
|
||||||
|
if (cmd.charAt() == '\\')
|
||||||
{
|
{
|
||||||
pattern = lastPattern;
|
cmd.inc();
|
||||||
|
if ("/?&".indexOf(cmd.charAt()) == -1)
|
||||||
|
{
|
||||||
|
// EMSG(_(e_backslash)); TODO
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cmd.charAt() != '&')
|
||||||
|
{
|
||||||
|
which_pat = RE_SEARCH; /* use last '/' pattern */
|
||||||
|
}
|
||||||
|
pat = new CharPointer(""); /* empty search pattern */
|
||||||
|
delimiter = cmd.charAt(); /* remember delimiter character */
|
||||||
|
cmd.inc();
|
||||||
|
}
|
||||||
|
else /* find the end of the regexp */
|
||||||
|
{
|
||||||
|
which_pat = RE_LAST; /* use last used regexp */
|
||||||
|
delimiter = cmd.charAt(); /* remember delimiter character */
|
||||||
|
cmd.inc();
|
||||||
|
pat = cmd.ref(0); /* remember start of search pat */
|
||||||
|
cmd = RegExp.skip_regexp(cmd, delimiter, true);
|
||||||
|
if (cmd.charAt() == delimiter) /* end delimiter found */
|
||||||
|
{
|
||||||
|
cmd.set('\u0000').inc(); /* replace it with a NUL */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Small incompatibility: vi sees '\n' as end of the command, but in
|
||||||
|
* Vim we want to use '\n' to find/substitute a NUL.
|
||||||
|
*/
|
||||||
|
sub = cmd.ref(0); /* remember the start of the substitution */
|
||||||
|
|
||||||
|
while (!cmd.isNul())
|
||||||
|
{
|
||||||
|
if (cmd.charAt() == delimiter) /* end delimiter found */
|
||||||
|
{
|
||||||
|
cmd.set('\u0000').inc(); /* replace it with a NUL */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (cmd.charAt(0) == '\\' && cmd.charAt(1) != 0) /* skip escaped characters */
|
||||||
|
{
|
||||||
|
cmd.inc();
|
||||||
|
}
|
||||||
|
cmd.inc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else /* use previous pattern and substitution */
|
||||||
try
|
|
||||||
{
|
{
|
||||||
sp = new RE(pattern, pflags, RESyntax.RE_SYNTAX_ED);
|
if (lastReplace == null) /* there is no previous command */
|
||||||
}
|
{
|
||||||
catch (Exception e)
|
// EMSG(_(e_nopresub)); TODO
|
||||||
{
|
return false;
|
||||||
return false;
|
}
|
||||||
|
pat = null; /* search_regcomp() will use previous pattern */
|
||||||
|
sub = new CharPointer(lastReplace);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastSearch = pattern;
|
/*
|
||||||
lastPattern = pattern;
|
* Find trailing options. When '&' is used, keep old options.
|
||||||
|
*/
|
||||||
if (replace.equals("~"))
|
if (cmd.charAt() == '&')
|
||||||
{
|
{
|
||||||
replace = lastReplace;
|
cmd.inc();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lastReplace = replace;
|
do_all = Options.getInstance().isSet("gdefault");
|
||||||
|
do_ask = false;
|
||||||
|
do_error = true;
|
||||||
|
do_print = false;
|
||||||
|
do_ic = 0;
|
||||||
|
}
|
||||||
|
while (!cmd.isNul())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Note that 'g' and 'c' are always inverted, also when p_ed is off.
|
||||||
|
* 'r' is never inverted.
|
||||||
|
*/
|
||||||
|
if (cmd.charAt() == 'g')
|
||||||
|
do_all = !do_all;
|
||||||
|
else if (cmd.charAt() == 'c')
|
||||||
|
do_ask = !do_ask;
|
||||||
|
else if (cmd.charAt() == 'e')
|
||||||
|
do_error = !do_error;
|
||||||
|
else if (cmd.charAt() == 'r') /* use last used regexp */
|
||||||
|
which_pat = RE_LAST;
|
||||||
|
else if (cmd.charAt() == 'p')
|
||||||
|
do_print = true;
|
||||||
|
else if (cmd.charAt() == 'i') /* ignore case */
|
||||||
|
do_ic = 'i';
|
||||||
|
else if (cmd.charAt() == 'I') /* don't ignore case */
|
||||||
|
do_ic = 'I';
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
cmd.inc();
|
||||||
}
|
}
|
||||||
|
|
||||||
int start = range.getStartOffset();
|
int line1 = range.getStartLine();
|
||||||
int end = range.getEndOffset();
|
int line2 = range.getEndLine();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check for a trailing count
|
||||||
|
*/
|
||||||
|
cmd = CharHelper.skipwhite(cmd);
|
||||||
|
if (CharacterClasses.isDigit(cmd.charAt()))
|
||||||
|
{
|
||||||
|
int i = CharHelper.getdigits(cmd);
|
||||||
|
if (i <= 0 && do_error)
|
||||||
|
{
|
||||||
|
// EMSG(_(e_zerocount)); TODO
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
line1 = line2;
|
||||||
|
line2 = EditorHelper.normalizeLine(editor, line1 + i - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check for trailing command or garbage
|
||||||
|
*/
|
||||||
|
cmd = CharHelper.skipwhite(cmd);
|
||||||
|
if (!cmd.isNul() && cmd.charAt() != '"') /* if not end-of-line or comment */
|
||||||
|
{
|
||||||
|
// EMSG(_(e_trailing)); TODO
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String pattern = "";
|
||||||
|
if (pat == null || pat.isNul())
|
||||||
|
{
|
||||||
|
switch (which_pat)
|
||||||
|
{
|
||||||
|
case RE_LAST:
|
||||||
|
pattern = lastPattern;
|
||||||
|
break;
|
||||||
|
case RE_SEARCH:
|
||||||
|
pattern = lastSearch;
|
||||||
|
break;
|
||||||
|
case RE_SUBST:
|
||||||
|
pattern = lastSubstitute;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pattern = pat.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
lastSubstitute = pattern;
|
||||||
|
lastPattern = pattern;
|
||||||
|
|
||||||
|
int start = editor.logicalPositionToOffset(new LogicalPosition(line1, 0));
|
||||||
|
int end = editor.logicalPositionToOffset(new LogicalPosition(line2, EditorHelper.getLineLength(editor, line2)));
|
||||||
|
|
||||||
|
RegExp sp;
|
||||||
|
RegExp.regmmatch_T regmatch = new RegExp.regmmatch_T();
|
||||||
|
sp = new RegExp();
|
||||||
|
regmatch.regprog = sp.vim_regcomp(pattern, 1);
|
||||||
|
if (regmatch.regprog == null)
|
||||||
|
{
|
||||||
|
if (do_error)
|
||||||
|
{
|
||||||
|
// EMSG(_(e_invcmd)); TODO
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the 'i' or 'I' flag overrules 'ignorecase' and 'smartcase' */
|
||||||
|
if (do_ic == 'i')
|
||||||
|
{
|
||||||
|
regmatch.rmm_ic = true;
|
||||||
|
}
|
||||||
|
else if (do_ic == 'I')
|
||||||
|
{
|
||||||
|
regmatch.rmm_ic = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ~ in the substitute pattern is replaced with the old pattern.
|
||||||
|
* We do it here once to avoid it to be replaced over and over again.
|
||||||
|
* But don't do it when it starts with "\=", then it's an expression.
|
||||||
|
*/
|
||||||
|
if (!(sub.charAt(0) == '\\' && sub.charAt(1) == '=') && lastReplace != null)
|
||||||
|
{
|
||||||
|
StringBuffer tmp = new StringBuffer(sub.toString());
|
||||||
|
int pos = 0;
|
||||||
|
while ((pos = tmp.indexOf("~", pos)) != -1)
|
||||||
|
{
|
||||||
|
if (pos == 0 || tmp.charAt(pos - 1) != '\\')
|
||||||
|
{
|
||||||
|
tmp.replace(pos, pos + 1, lastReplace);
|
||||||
|
pos += lastReplace.length();
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
sub = new CharPointer(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastReplace = sub.toString();
|
||||||
|
|
||||||
logger.debug("search range=[" + start + "," + end + "]");
|
logger.debug("search range=[" + start + "," + end + "]");
|
||||||
logger.debug("pattern="+pattern + ", replace="+replace);
|
logger.debug("pattern="+pattern + ", replace="+sub);
|
||||||
int from = 0;
|
|
||||||
int lastMatch = -1;
|
int lastMatch = -1;
|
||||||
boolean found = true;
|
boolean found = true;
|
||||||
int lastLine = -1;
|
int lastLine = -1;
|
||||||
boolean checkConfirm = true;
|
int searchcol = 0;
|
||||||
while (found)
|
boolean firstMatch = true;
|
||||||
|
boolean got_quit = false;
|
||||||
|
for (int lnum = line1; lnum <= line2 && !got_quit;)
|
||||||
{
|
{
|
||||||
char[] chars = editor.getDocument().getChars();
|
LogicalPosition newpos = null;
|
||||||
CharBuffer buf = CharBuffer.wrap(chars, start, end - start);
|
int nmatch = sp.vim_regexec_multi(regmatch, editor, lnum, searchcol);
|
||||||
logger.debug("buf=" + buf);
|
found = nmatch > 0;
|
||||||
REMatch matcher = sp.getMatch(buf, from);
|
|
||||||
found = matcher != null;
|
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
int spos = matcher.getStartIndex();
|
if (firstMatch)
|
||||||
int epos = matcher.getEndIndex();
|
{
|
||||||
String match = matcher.substituteInto(replace);
|
CommandGroups.getInstance().getMark().saveJumpLocation(editor, context);
|
||||||
logger.debug("found match[" + spos + "," + epos + "] - replace " + match);
|
firstMatch = false;
|
||||||
|
}
|
||||||
|
|
||||||
int line = editor.offsetToLogicalPosition(start + spos).line;
|
String match = sp.vim_regsub_multi(regmatch, lnum, sub, 1, true);
|
||||||
if ((flags & GLOBAL) != 0 || line != lastLine)
|
//logger.debug("found match[" + spos + "," + epos + "] - replace " + match);
|
||||||
|
|
||||||
|
int line = lnum + regmatch.startpos[0].lnum;
|
||||||
|
LogicalPosition startpos = new LogicalPosition(lnum + regmatch.startpos[0].lnum,
|
||||||
|
regmatch.startpos[0].col);
|
||||||
|
LogicalPosition endpos = new LogicalPosition(lnum + regmatch.endpos[0].lnum,
|
||||||
|
regmatch.endpos[0].col);
|
||||||
|
int startoff = editor.logicalPositionToOffset(startpos);
|
||||||
|
int endoff = editor.logicalPositionToOffset(endpos);
|
||||||
|
int newend = startoff + match.length();
|
||||||
|
|
||||||
|
if (do_all || line != lastLine)
|
||||||
{
|
{
|
||||||
boolean doReplace = true;
|
boolean doReplace = true;
|
||||||
if ((flags & CONFIRM) != 0 && checkConfirm)
|
if (do_ask)
|
||||||
{
|
{
|
||||||
editor.getSelectionModel().setSelection(start + spos, start + epos);
|
//editor.getSelectionModel().setSelection(startoff, endoff);
|
||||||
|
RangeHighlighter hl = highlightMatch(editor, startoff, endoff);
|
||||||
int choice = JOptionPane.showOptionDialog(null, "Replace with " + match + " ?",
|
int choice = JOptionPane.showOptionDialog(null, "Replace with " + match + " ?",
|
||||||
"Confirm Replace", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null,
|
"Confirm Replace", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null,
|
||||||
getConfirmButtons(), null);
|
getConfirmButtons(), null);
|
||||||
editor.getSelectionModel().removeSelection();
|
//editor.getSelectionModel().removeSelection();
|
||||||
|
editor.getMarkupModel().removeHighlighter(hl);
|
||||||
switch (choice)
|
switch (choice)
|
||||||
{
|
{
|
||||||
case 0: // Yes
|
case 0: // Yes
|
||||||
@ -166,14 +359,17 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
doReplace = false;
|
doReplace = false;
|
||||||
break;
|
break;
|
||||||
case 2: // All
|
case 2: // All
|
||||||
checkConfirm = false;
|
do_ask = false;
|
||||||
break;
|
break;
|
||||||
case JOptionPane.CLOSED_OPTION:
|
case JOptionPane.CLOSED_OPTION:
|
||||||
case 3: // Quit
|
case 3: // Quit
|
||||||
found = false;
|
found = false;
|
||||||
doReplace = false;
|
doReplace = false;
|
||||||
|
got_quit = true;
|
||||||
break;
|
break;
|
||||||
case 4: // Last
|
case 4: // Last
|
||||||
|
do_all = false;
|
||||||
|
line2 = lnum;
|
||||||
found = false;
|
found = false;
|
||||||
doReplace = true;
|
doReplace = true;
|
||||||
break;
|
break;
|
||||||
@ -182,15 +378,35 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
|
|
||||||
if (doReplace)
|
if (doReplace)
|
||||||
{
|
{
|
||||||
lastLine = line;
|
editor.getDocument().replaceString(startoff, endoff, match);
|
||||||
editor.getDocument().replaceString(start + spos, start + epos, match);
|
lastMatch = startoff;
|
||||||
lastMatch = start + spos;
|
newpos = editor.offsetToLogicalPosition(newend);
|
||||||
|
|
||||||
|
int diff = newpos.line - endpos.line;
|
||||||
|
line2 += diff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int diff = match.length() - (epos - spos);
|
lastLine = line;
|
||||||
end += diff;
|
|
||||||
from = epos + diff;
|
lnum += nmatch - 1;
|
||||||
|
if (do_all)
|
||||||
|
{
|
||||||
|
if (newpos != null)
|
||||||
|
searchcol = newpos.column;
|
||||||
|
else
|
||||||
|
searchcol = endpos.column;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
searchcol = 0;
|
||||||
|
lnum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lnum++;
|
||||||
|
searchcol = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,22 +528,23 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
type = '?';
|
type = '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - broke - doesn't handle ranges and backslashes
|
|
||||||
if (command.length() > 0)
|
if (command.length() > 0)
|
||||||
{
|
{
|
||||||
StringTokenizer tokenizer = new StringTokenizer(command, Character.toString(type));
|
|
||||||
if (command.charAt(0) != type)
|
if (command.charAt(0) != type)
|
||||||
{
|
{
|
||||||
pattern = tokenizer.nextToken();
|
CharPointer p = new CharPointer(command);
|
||||||
|
CharPointer end = RegExp.skip_regexp(p.ref(0), type, true);
|
||||||
|
pattern = p.substring(end.pointer() - p.pointer());
|
||||||
logger.debug("pattern=" + pattern);
|
logger.debug("pattern=" + pattern);
|
||||||
if (!tokenizer.hasMoreTokens())
|
if (p.charAt() != type)
|
||||||
{
|
{
|
||||||
logger.debug("no offset");
|
logger.debug("no offset");
|
||||||
offset = "";
|
offset = "";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
offset = tokenizer.nextToken("\n").substring(1);
|
p.inc();
|
||||||
|
offset = p.toString();
|
||||||
logger.debug("offset=" + offset);
|
logger.debug("offset=" + offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -337,12 +554,13 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
offset = tokenizer.nextToken("\n").substring(1);
|
offset = command.substring(1);
|
||||||
logger.debug("offset=" + offset);
|
logger.debug("offset=" + offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastSearch = pattern;
|
lastSearch = pattern;
|
||||||
|
lastPattern = pattern;
|
||||||
lastOffset = offset;
|
lastOffset = offset;
|
||||||
lastDir = dir;
|
lastDir = dir;
|
||||||
|
|
||||||
@ -381,10 +599,6 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
lastDir = dir;
|
lastDir = dir;
|
||||||
|
|
||||||
int res = findItOffset(editor, context, editor.getCaretModel().getOffset(), count, lastDir, true);
|
int res = findItOffset(editor, context, editor.getCaretModel().getOffset(), count, lastDir, true);
|
||||||
if (res != -1)
|
|
||||||
{
|
|
||||||
MotionGroup.moveCaret(editor, context, res);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -408,6 +622,8 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//highlightMatch(editor, range.getStartOffset(), range.getEndOffset());
|
||||||
|
|
||||||
ParsePosition pp = new ParsePosition(0);
|
ParsePosition pp = new ParsePosition(0);
|
||||||
int res = range.getStartOffset();
|
int res = range.getStartOffset();
|
||||||
|
|
||||||
@ -515,38 +731,66 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
int pflags = RE.REG_MULTILINE;
|
int pflags = RE.REG_MULTILINE;
|
||||||
if (shouldIgnoreCase(lastSearch, noSmartCase))
|
if (shouldIgnoreCase(lastSearch, noSmartCase))
|
||||||
{
|
{
|
||||||
pflags |= RE.REG_ICASE;
|
pflags |= RE.REG_ICASE;
|
||||||
}
|
}
|
||||||
RE sp;
|
*/
|
||||||
try
|
//RE sp;
|
||||||
{
|
RegExp sp;
|
||||||
sp = new RE(lastSearch, pflags, RESyntax.RE_SYNTAX_ED);
|
RegExp.regmmatch_T regmatch = new RegExp.regmmatch_T();
|
||||||
}
|
regmatch.rmm_ic = shouldIgnoreCase(lastSearch, noSmartCase);
|
||||||
catch (REException e)
|
sp = new RegExp();
|
||||||
|
regmatch.regprog = sp.vim_regcomp(lastSearch, 1);
|
||||||
|
if (regmatch == null)
|
||||||
{
|
{
|
||||||
logger.debug("bad pattern: " + lastSearch);
|
logger.debug("bad pattern: " + lastSearch);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
int extra_col = 1;
|
int extra_col = 1;
|
||||||
int startcol = -1;
|
int startcol = -1;
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
boolean match_ok = true;
|
boolean match_ok = true;
|
||||||
LogicalPosition pos = editor.offsetToLogicalPosition(startOffset);
|
LogicalPosition pos = editor.offsetToLogicalPosition(startOffset);
|
||||||
LogicalPosition endpos = null;
|
LogicalPosition endpos = null;
|
||||||
REMatch match = null;
|
//REMatch match = null;
|
||||||
|
*/
|
||||||
|
|
||||||
do /* loop for count */
|
LogicalPosition lpos = editor.offsetToLogicalPosition(startOffset);
|
||||||
|
RegExp.lpos_T pos = new RegExp.lpos_T();
|
||||||
|
pos.lnum = lpos.line;
|
||||||
|
pos.col = lpos.column;
|
||||||
|
|
||||||
|
int found;
|
||||||
|
int lnum; /* no init to shut up Apollo cc */
|
||||||
|
//RegExp.regmmatch_T regmatch;
|
||||||
|
CharPointer ptr = null;
|
||||||
|
int matchcol;
|
||||||
|
int startcol;
|
||||||
|
RegExp.lpos_T endpos = new RegExp.lpos_T();
|
||||||
|
int loop;
|
||||||
|
RegExp.lpos_T start_pos;
|
||||||
|
boolean at_first_line;
|
||||||
|
int extra_col = 1;
|
||||||
|
boolean match_ok;
|
||||||
|
long nmatched;
|
||||||
|
//int submatch = 0;
|
||||||
|
int first_lnum;
|
||||||
|
boolean p_ws = Options.getInstance().isSet("wrapscan");
|
||||||
|
|
||||||
|
do /* loop for count */
|
||||||
{
|
{
|
||||||
LogicalPosition start_pos = pos; /* remember start pos for detecting no match */
|
start_pos = new RegExp.lpos_T(pos); /* remember start pos for detecting no match */
|
||||||
found = false; /* default: not found */
|
found = 0; /* default: not found */
|
||||||
boolean at_first_line = true; /* default: start in first line */
|
at_first_line = true; /* default: start in first line */
|
||||||
if (pos.line == -1) /* correct lnum for when starting in line 0 */
|
if (pos.lnum == -1) /* correct lnum for when starting in line 0 */
|
||||||
{
|
{
|
||||||
pos = new LogicalPosition(0, 0);
|
pos.lnum = 0;
|
||||||
|
pos.col = 0;
|
||||||
at_first_line = false; /* not in first line now */
|
at_first_line = false; /* not in first line now */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,42 +798,33 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
* Start searching in current line, unless searching backwards and
|
* Start searching in current line, unless searching backwards and
|
||||||
* we're in column 0.
|
* we're in column 0.
|
||||||
*/
|
*/
|
||||||
int lnum;
|
if (dir == -1 && start_pos.col == 0)
|
||||||
if (dir == -1 && start_pos.column == 0)
|
|
||||||
{
|
{
|
||||||
lnum = pos.line - 1;
|
lnum = pos.lnum - 1;
|
||||||
at_first_line = false;
|
at_first_line = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
lnum = pos.line;
|
|
||||||
|
|
||||||
for (int loop = 0; loop <= 1; ++loop) /* loop twice if 'wrapscan' set */
|
|
||||||
{
|
{
|
||||||
for ( ; lnum >= 0 && lnum < EditorHelper.getLineCount(editor);
|
lnum = pos.lnum;
|
||||||
lnum += dir, at_first_line = false)
|
}
|
||||||
|
|
||||||
|
for (loop = 0; loop <= 1; ++loop) /* loop twice if 'wrapscan' set */
|
||||||
|
{
|
||||||
|
int lineCount = EditorHelper.getLineCount(editor);
|
||||||
|
for ( ; lnum >= 0 && lnum < lineCount; lnum += dir, at_first_line = false)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Look for a match somewhere in the line.
|
* Look for a match somewhere in the line.
|
||||||
*/
|
*/
|
||||||
int first_lnum = lnum;
|
first_lnum = lnum;
|
||||||
/*
|
nmatched = sp.vim_regexec_multi(regmatch, editor, lnum, 0);
|
||||||
nmatched = vim_regexec_multi(®match, win, buf,
|
|
||||||
lnum, (colnr_T)0);
|
|
||||||
*/
|
|
||||||
match = sp.getMatch(EditorHelper.getLineBuffer(editor, lnum), 0);
|
|
||||||
int nmatched = match == null ? 0 : 1;
|
|
||||||
/* Abort searching on an error (e.g., out of stack). */
|
|
||||||
/*
|
|
||||||
if (called_emsg)
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
if (nmatched > 0)
|
if (nmatched > 0)
|
||||||
{
|
{
|
||||||
/* match may actually be in another line when using \zs */
|
/* match may actually be in another line when using \zs */
|
||||||
//lnum += regmatch.startpos[0].lnum;
|
lnum += regmatch.startpos[0].lnum;
|
||||||
int ptr = EditorHelper.getLineStartOffset(editor, lnum); //ptr = ml_get_buf(buf, lnum, false);
|
ptr = new CharPointer(EditorHelper.getLineBuffer(editor, lnum));
|
||||||
startcol = match.getStartIndex(); //regmatch.startpos[0].col;
|
startcol = regmatch.startpos[0].col;
|
||||||
endpos = new LogicalPosition(lnum, match.getEndIndex()); //endpos = regmatch.endpos[0];
|
endpos = regmatch.endpos[0];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Forward search in the first line: match should be after
|
* Forward search in the first line: match should be after
|
||||||
@ -604,34 +839,38 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
* one back afterwards, compare with that position,
|
* one back afterwards, compare with that position,
|
||||||
* otherwise "/$" will get stuck on end of line.
|
* otherwise "/$" will get stuck on end of line.
|
||||||
*/
|
*/
|
||||||
while (startcol < start_pos.column + extra_col)
|
while ((startcol - (startcol == ptr.strlen() ? 1 : 0)) < (start_pos.col + extra_col))
|
||||||
{
|
{
|
||||||
int matchcol = startcol;
|
if (nmatched > 1)
|
||||||
if (matchcol < EditorHelper.getLineLength(editor, lnum))//(ptr[matchcol] != NUL)
|
|
||||||
{
|
{
|
||||||
++matchcol;
|
/* end is in next line, thus no match in
|
||||||
|
* this line */
|
||||||
|
match_ok = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (matchcol == EditorHelper.getLineLength(editor, lnum))//ptr[matchcol] == NUL
|
matchcol = endpos.col;
|
||||||
|
/* for empty match: advance one char */
|
||||||
|
if (matchcol == startcol && ptr.charAt(matchcol) != '\u0000')
|
||||||
|
{
|
||||||
|
++matchcol;
|
||||||
|
}
|
||||||
|
if (ptr.charAt(matchcol) == '\u0000' ||
|
||||||
|
(nmatched = sp.vim_regexec_multi(regmatch, editor, lnum, matchcol)) == 0)
|
||||||
{
|
{
|
||||||
match_ok = false;
|
match_ok = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
match = sp.getMatch(EditorHelper.getLineBuffer(editor, lnum), matchcol);
|
startcol = regmatch.startpos[0].col;
|
||||||
nmatched = match == null ? 0 : 1;
|
endpos = regmatch.endpos[0];
|
||||||
if (nmatched == 0)
|
|
||||||
{
|
|
||||||
match_ok = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
startcol = match.getStartIndex(); //regmatch.startpos[0].col;
|
|
||||||
endpos = new LogicalPosition(lnum, match.getEndIndex()); //endpos = regmatch.endpos[0];
|
|
||||||
|
|
||||||
/* Need to get the line pointer again, a
|
/* Need to get the line pointer again, a
|
||||||
* multi-line search may have made it invalid. */
|
* multi-line search may have made it invalid. */
|
||||||
//ptr = ml_get_buf(buf, lnum, false);
|
ptr = new CharPointer(EditorHelper.getLineBuffer(editor, lnum));
|
||||||
}
|
}
|
||||||
if (!match_ok)
|
if (!match_ok)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (dir == -1)
|
if (dir == -1)
|
||||||
{
|
{
|
||||||
@ -645,17 +884,18 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
match_ok = false;
|
match_ok = false;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (!at_first_line || (match.getEndIndex() + extra_col <= start_pos.column))
|
if (!at_first_line || (regmatch.startpos[0].col + extra_col <= start_pos.col))
|
||||||
{
|
{
|
||||||
/* Remember this position, we use it if it's
|
/* Remember this position, we use it if it's
|
||||||
* the last match in the line. */
|
* the last match in the line. */
|
||||||
match_ok = true;
|
match_ok = true;
|
||||||
startcol = match.getStartIndex(); //regmatch.startpos[0].col;
|
startcol = regmatch.startpos[0].col;
|
||||||
endpos = new LogicalPosition(lnum, match.getEndIndex());
|
endpos = regmatch.endpos[0];
|
||||||
//endpos = regmatch.endpos[0];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We found a valid match, now check if there is
|
* We found a valid match, now check if there is
|
||||||
@ -664,25 +904,25 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
* of the match, otherwise continue one position
|
* of the match, otherwise continue one position
|
||||||
* forward.
|
* forward.
|
||||||
*/
|
*/
|
||||||
int matchcol = startcol;
|
if (nmatched > 1)
|
||||||
if (matchcol < EditorHelper.getLineLength(editor, lnum))//(ptr[matchcol] != NUL)
|
|
||||||
{
|
|
||||||
++matchcol;
|
|
||||||
}
|
|
||||||
if (matchcol == EditorHelper.getLineLength(editor, lnum))//ptr[matchcol] == NUL
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
match = sp.getMatch(EditorHelper.getLineBuffer(editor, lnum), matchcol);
|
matchcol = endpos.col;
|
||||||
nmatched = match == null ? 0 : 1;
|
/* for empty match: advance one char */
|
||||||
if (nmatched == 0)
|
if (matchcol == startcol && ptr.charAt(matchcol) != '\u0000')
|
||||||
|
{
|
||||||
|
++matchcol;
|
||||||
|
}
|
||||||
|
if (ptr.charAt(matchcol) == '\u0000' ||
|
||||||
|
(nmatched = sp.vim_regexec_multi(regmatch, editor, lnum, matchcol)) == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need to get the line pointer again, a
|
/* Need to get the line pointer again, a
|
||||||
* multi-line search may have made it invalid. */
|
* multi-line search may have made it invalid. */
|
||||||
//ptr = ml_get_buf(buf, lnum, false);
|
ptr = new CharPointer(EditorHelper.getLineBuffer(editor, lnum));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -690,36 +930,30 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
* this match.
|
* this match.
|
||||||
*/
|
*/
|
||||||
if (!match_ok)
|
if (!match_ok)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = new LogicalPosition(lnum, startcol);
|
pos.lnum = lnum;
|
||||||
found = true;
|
pos.col = startcol;
|
||||||
|
endpos.lnum += first_lnum;
|
||||||
|
found = 1;
|
||||||
|
|
||||||
/* Set variables used for 'incsearch' highlighting. */
|
/* Set variables used for 'incsearch' highlighting. */
|
||||||
//search_match_lines = endpos.lnum - (lnum - first_lnum);
|
//search_match_lines = endpos.lnum - (lnum - first_lnum);
|
||||||
//search_match_endcol = endpos.col;
|
//search_match_endcol = endpos.col;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//line_breakcheck(); /* stop if ctrl-C typed */
|
//line_breakcheck(); /* stop if ctrl-C typed */
|
||||||
//if (got_int)
|
//if (got_int)
|
||||||
// break;
|
// break;
|
||||||
|
|
||||||
/* Cancel searching if a character was typed. Used for
|
|
||||||
* 'incsearch'. Don't check too often, that would slowdown
|
|
||||||
* searching too much. */
|
|
||||||
/*
|
|
||||||
if ((options & SEARCH_PEEK)
|
|
||||||
&& ((lnum - pos.lnum) & 0x3f) == 0
|
|
||||||
&& char_avail())
|
|
||||||
{
|
|
||||||
break_loop = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (loop == 1 && lnum == start_pos.line)
|
if (loop != 0 && lnum == start_pos.lnum)
|
||||||
break; /* if second loop, stop where started */
|
{
|
||||||
|
break; /* if second loop, stop where started */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
at_first_line = false;
|
at_first_line = false;
|
||||||
|
|
||||||
@ -727,8 +961,10 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
* stop the search if wrapscan isn't set, after an interrupt and
|
* stop the search if wrapscan isn't set, after an interrupt and
|
||||||
* after a match
|
* after a match
|
||||||
*/
|
*/
|
||||||
if (found)
|
if (!p_ws || found != 0)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If 'wrapscan' is set we continue at the other end of the file.
|
* If 'wrapscan' is set we continue at the other end of the file.
|
||||||
@ -739,36 +975,23 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
*/
|
*/
|
||||||
if (dir == -1) /* start second loop at the other end */
|
if (dir == -1) /* start second loop at the other end */
|
||||||
{
|
{
|
||||||
lnum = EditorHelper.getLineCount(editor) - 1;//buf.b_ml.ml_line_count;
|
lnum = lineCount - 1;
|
||||||
/*
|
//if (!shortmess(SHM_SEARCH) && (options & SEARCH_MSG))
|
||||||
if (!shortmess(SHM_SEARCH) && (options & SEARCH_MSG))
|
// give_warning((char_u *)_(top_bot_msg), TRUE);
|
||||||
give_warning((char_u *)_(top_bot_msg), true);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lnum = 0;
|
lnum = 0;
|
||||||
/*
|
//if (!shortmess(SHM_SEARCH) && (options & SEARCH_MSG))
|
||||||
if (!shortmess(SHM_SEARCH) && (options & SEARCH_MSG))
|
// give_warning((char_u *)_(bot_top_msg), TRUE);
|
||||||
give_warning((char_u *)_(bot_top_msg), true);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Options.getInstance().isSet("wrapscan"))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
//if (got_int || called_emsg || break_loop)
|
||||||
if (got_int || called_emsg || break_loop)
|
// break;
|
||||||
break;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
while (--count > 0 && found); /* stop after count matches or no match */
|
while (--count > 0 && found != 0); /* stop after count matches or no match */
|
||||||
|
|
||||||
//vim_free(regmatch.regprog);
|
if (found == 0) /* did not find it */
|
||||||
|
|
||||||
if (!found) /* did not find it */
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
if (got_int)
|
if (got_int)
|
||||||
@ -783,30 +1006,36 @@ public class SearchGroup extends AbstractActionGroup
|
|||||||
EMSG2(_("E385: search hit BOTTOM without match for: %s"), mr_pattern);
|
EMSG2(_("E385: search hit BOTTOM without match for: %s"), mr_pattern);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
res = null; //return FAIL;
|
return null;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
res = new TextRange(editor.logicalPositionToOffset(pos), editor.logicalPositionToOffset(endpos));
|
|
||||||
//highlightMatch(editor, res.getStartOffset(), res.getEndOffset());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return new TextRange(editor.logicalPositionToOffset(new LogicalPosition(pos.lnum, pos.col)),
|
||||||
|
editor.logicalPositionToOffset(new LogicalPosition(endpos.lnum, endpos.col)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void highlightMatch(Editor editor, int start, int end)
|
private RangeHighlighter highlightMatch(Editor editor, int start, int end)
|
||||||
{
|
{
|
||||||
editor.getMarkupModel().addRangeHighlighter(start, end, HighlighterLayer.SELECTION,
|
return editor.getMarkupModel().addRangeHighlighter(start, end, HighlighterLayer.SELECTION,
|
||||||
new TextAttributes(Color.BLACK, Color.YELLOW, null, null, 0), HighlighterTargetArea.EXACT_RANGE);
|
new TextAttributes(Color.BLACK, Color.YELLOW, null, null, 0), HighlighterTargetArea.EXACT_RANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String lastSearch;
|
private String lastSearch;
|
||||||
private String lastPattern;
|
private String lastPattern;
|
||||||
|
private String lastSubstitute;
|
||||||
private String lastReplace;
|
private String lastReplace;
|
||||||
private String lastOffset;
|
private String lastOffset;
|
||||||
private int lastDir;
|
private int lastDir;
|
||||||
private int lastFlags;
|
|
||||||
private Object[] confirmBtns;
|
private Object[] confirmBtns;
|
||||||
|
|
||||||
|
private boolean do_all = false; /* do multiple substitutions per line */
|
||||||
|
private boolean do_ask = false; /* ask for confirmation */
|
||||||
|
private boolean do_error = true; /* if false, ignore errors */
|
||||||
|
private boolean do_print = false; /* print last line with subs. */
|
||||||
|
private char do_ic = 0; /* ignore case flag */
|
||||||
|
|
||||||
|
private static final int RE_LAST = 1;
|
||||||
|
private static final int RE_SEARCH = 2;
|
||||||
|
private static final int RE_SUBST = 3;
|
||||||
|
|
||||||
private static Logger logger = Logger.getInstance(SearchGroup.class.getName());
|
private static Logger logger = Logger.getInstance(SearchGroup.class.getName());
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import com.maddyhome.idea.vim.handler.AbstractEditorActionHandler;
|
|||||||
import com.maddyhome.idea.vim.undo.UndoManager;
|
import com.maddyhome.idea.vim.undo.UndoManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TODO - doesn't work for repeating last 'R' command
|
||||||
*/
|
*/
|
||||||
public class RepeatChangeHandler extends AbstractEditorActionHandler
|
public class RepeatChangeHandler extends AbstractEditorActionHandler
|
||||||
{
|
{
|
||||||
|
@ -21,12 +21,11 @@ package com.maddyhome.idea.vim.handler.change.change;
|
|||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext;
|
import com.intellij.openapi.actionSystem.DataContext;
|
||||||
import com.intellij.openapi.editor.Editor;
|
import com.intellij.openapi.editor.Editor;
|
||||||
import com.intellij.openapi.util.TextRange;
|
|
||||||
import com.maddyhome.idea.vim.command.Argument;
|
import com.maddyhome.idea.vim.command.Argument;
|
||||||
import com.maddyhome.idea.vim.ex.Ranges;
|
import com.maddyhome.idea.vim.ex.LineRange;
|
||||||
import com.maddyhome.idea.vim.group.CommandGroups;
|
import com.maddyhome.idea.vim.group.CommandGroups;
|
||||||
import com.maddyhome.idea.vim.group.SearchGroup;
|
|
||||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler;
|
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler;
|
||||||
|
import com.maddyhome.idea.vim.helper.EditorHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@ -34,8 +33,7 @@ public class ChangeLastGlobalSearchReplaceHandler extends ChangeEditorActionHand
|
|||||||
{
|
{
|
||||||
public boolean execute(Editor editor, DataContext context, int count, int rawCount, Argument argument)
|
public boolean execute(Editor editor, DataContext context, int count, int rawCount, Argument argument)
|
||||||
{
|
{
|
||||||
TextRange range = Ranges.getFileTextRange(editor, context);
|
LineRange range = new LineRange(0, EditorHelper.getLineCount(editor) - 1);
|
||||||
return CommandGroups.getInstance().getSearch().searchAndReplace(editor, context, range, "", "~",
|
return CommandGroups.getInstance().getSearch().searchAndReplace(editor, context, range, "s", "//~/&");
|
||||||
SearchGroup.KEEP_FLAGS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,11 @@ package com.maddyhome.idea.vim.handler.change.change;
|
|||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext;
|
import com.intellij.openapi.actionSystem.DataContext;
|
||||||
import com.intellij.openapi.editor.Editor;
|
import com.intellij.openapi.editor.Editor;
|
||||||
import com.intellij.openapi.util.TextRange;
|
|
||||||
import com.maddyhome.idea.vim.command.Argument;
|
import com.maddyhome.idea.vim.command.Argument;
|
||||||
import com.maddyhome.idea.vim.ex.Ranges;
|
import com.maddyhome.idea.vim.ex.LineRange;
|
||||||
import com.maddyhome.idea.vim.group.CommandGroups;
|
import com.maddyhome.idea.vim.group.CommandGroups;
|
||||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler;
|
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler;
|
||||||
|
import com.maddyhome.idea.vim.helper.EditorHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@ -33,7 +33,8 @@ public class ChangeLastSearchReplaceHandler extends ChangeEditorActionHandler
|
|||||||
{
|
{
|
||||||
public boolean execute(Editor editor, DataContext context, int count, int rawCount, Argument argument)
|
public boolean execute(Editor editor, DataContext context, int count, int rawCount, Argument argument)
|
||||||
{
|
{
|
||||||
TextRange range = Ranges.getCurrentLineRange(editor, context);
|
int line = EditorHelper.getCurrentLogicalLine(editor);
|
||||||
return CommandGroups.getInstance().getSearch().searchAndReplace(editor, context, range, "", "~", 0);
|
LineRange range = new LineRange(line, line);
|
||||||
|
return CommandGroups.getInstance().getSearch().searchAndReplace(editor, context, range, "s", "//~/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import com.intellij.openapi.editor.Editor;
|
|||||||
import com.maddyhome.idea.vim.command.Argument;
|
import com.maddyhome.idea.vim.command.Argument;
|
||||||
import com.maddyhome.idea.vim.command.Command;
|
import com.maddyhome.idea.vim.command.Command;
|
||||||
import com.maddyhome.idea.vim.group.MotionGroup;
|
import com.maddyhome.idea.vim.group.MotionGroup;
|
||||||
|
import com.maddyhome.idea.vim.group.CommandGroups;
|
||||||
import com.maddyhome.idea.vim.handler.AbstractEditorActionHandler;
|
import com.maddyhome.idea.vim.handler.AbstractEditorActionHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,6 +42,10 @@ public abstract class MotionEditorActionHandler extends AbstractEditorActionHand
|
|||||||
}
|
}
|
||||||
else if (offset >= 0)
|
else if (offset >= 0)
|
||||||
{
|
{
|
||||||
|
if ((cmd.getFlags() & Command.FLAG_SAVE_JUMP) != 0)
|
||||||
|
{
|
||||||
|
CommandGroups.getInstance().getMark().saveJumpLocation(editor, context);
|
||||||
|
}
|
||||||
MotionGroup.moveCaret(editor, context, offset);
|
MotionGroup.moveCaret(editor, context, offset);
|
||||||
postMove(editor, context, cmd);
|
postMove(editor, context, cmd);
|
||||||
|
|
||||||
|
@ -82,7 +82,12 @@ public class SearchEntryHandler extends AbstractEditorActionHandler
|
|||||||
{
|
{
|
||||||
logger.debug("processing search");
|
logger.debug("processing search");
|
||||||
CommandEntryPanel.getInstance().deactivate(true);
|
CommandEntryPanel.getInstance().deactivate(true);
|
||||||
CommandGroups.getInstance().getSearch().search(editor, context, e.getActionCommand(), count, flags);
|
int res = CommandGroups.getInstance().getSearch().search(editor, context, e.getActionCommand(),
|
||||||
|
count, flags, true);
|
||||||
|
if (res == -1)
|
||||||
|
{
|
||||||
|
VimPlugin.indicateError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception bad)
|
catch (Exception bad)
|
||||||
{
|
{
|
||||||
|
@ -82,7 +82,7 @@ public class SearchEntryHandler extends AbstractEditorActionHandler
|
|||||||
{
|
{
|
||||||
logger.debug("processing search");
|
logger.debug("processing search");
|
||||||
CommandEntryPanel.getInstance().deactivate(true);
|
CommandEntryPanel.getInstance().deactivate(true);
|
||||||
CommandGroups.getInstance().getSearch().search(editor, context, e.getActionCommand(), count, flags);
|
CommandGroups.getInstance().getSearch().search(editor, context, e.getActionCommand(), count, flags, true);
|
||||||
}
|
}
|
||||||
catch (Exception bad)
|
catch (Exception bad)
|
||||||
{
|
{
|
||||||
|
33
src/com/maddyhome/idea/vim/regexp/Ascii.java
Normal file
33
src/com/maddyhome/idea/vim/regexp/Ascii.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package com.maddyhome.idea.vim.regexp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IdeaVim - A Vim emulator plugin for IntelliJ Idea
|
||||||
|
* Copyright (C) 2003 Rick Maddy
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface Ascii
|
||||||
|
{
|
||||||
|
char BS = 010;
|
||||||
|
char TAB = 011;
|
||||||
|
char NL = 012;
|
||||||
|
char CR = 015;
|
||||||
|
char ESC = 033;
|
||||||
|
char Ctrl_H = 8;
|
||||||
|
}
|
50
src/com/maddyhome/idea/vim/regexp/CharHelper.java
Normal file
50
src/com/maddyhome/idea/vim/regexp/CharHelper.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package com.maddyhome.idea.vim.regexp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IdeaVim - A Vim emulator plugin for IntelliJ Idea
|
||||||
|
* Copyright (C) 2003 Rick Maddy
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CharHelper
|
||||||
|
{
|
||||||
|
public static CharPointer skipwhite(CharPointer ptr)
|
||||||
|
{
|
||||||
|
while (CharacterClasses.isWhite(ptr.charAt()))
|
||||||
|
{
|
||||||
|
ptr.inc();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getdigits(CharPointer ptr)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
while (CharacterClasses.isDigit(ptr.charAt()))
|
||||||
|
{
|
||||||
|
res = res * 10 + (ptr.charAt() - '0');
|
||||||
|
ptr.inc();
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CharHelper() {}
|
||||||
|
}
|
349
src/com/maddyhome/idea/vim/regexp/CharPointer.java
Normal file
349
src/com/maddyhome/idea/vim/regexp/CharPointer.java
Normal file
@ -0,0 +1,349 @@
|
|||||||
|
package com.maddyhome.idea.vim.regexp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IdeaVim - A Vim emulator plugin for IntelliJ Idea
|
||||||
|
* Copyright (C) 2003 Rick Maddy
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.nio.CharBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CharPointer
|
||||||
|
{
|
||||||
|
public static final CharPointer INIT = new CharPointer();
|
||||||
|
|
||||||
|
public CharPointer(String text)
|
||||||
|
{
|
||||||
|
seq = text;
|
||||||
|
readonly = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharPointer(CharBuffer text)
|
||||||
|
{
|
||||||
|
seq = text;
|
||||||
|
readonly = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharPointer(StringBuffer text)
|
||||||
|
{
|
||||||
|
seq = text;
|
||||||
|
readonly = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CharPointer(CharPointer ptr, int offset)
|
||||||
|
{
|
||||||
|
seq = ptr.seq;
|
||||||
|
readonly = ptr.readonly;
|
||||||
|
pointer = ptr.pointer + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CharPointer()
|
||||||
|
{
|
||||||
|
seq = null;
|
||||||
|
pointer = -1;
|
||||||
|
readonly = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int pointer()
|
||||||
|
{
|
||||||
|
return pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInit()
|
||||||
|
{
|
||||||
|
return seq == null && pointer == -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharPointer set(char ch)
|
||||||
|
{
|
||||||
|
return set(ch, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharPointer set(char ch, int offset)
|
||||||
|
{
|
||||||
|
if (seq == null)
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readonly)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("readonly string");
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuffer data = (StringBuffer)seq;
|
||||||
|
while (pointer + offset >= data.length())
|
||||||
|
{
|
||||||
|
data.append('\u0000');
|
||||||
|
}
|
||||||
|
data.setCharAt(pointer + offset, ch);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char charAtInc()
|
||||||
|
{
|
||||||
|
char res = charAt(0);
|
||||||
|
inc();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char charAt()
|
||||||
|
{
|
||||||
|
return charAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public char charAt(int offset)
|
||||||
|
{
|
||||||
|
if (end(offset))
|
||||||
|
{
|
||||||
|
return '\u0000';
|
||||||
|
}
|
||||||
|
|
||||||
|
return seq.charAt(pointer + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharPointer inc()
|
||||||
|
{
|
||||||
|
return inc(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharPointer inc(int cnt)
|
||||||
|
{
|
||||||
|
pointer += cnt;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharPointer dec()
|
||||||
|
{
|
||||||
|
return dec(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharPointer dec(int cnt)
|
||||||
|
{
|
||||||
|
pointer -= cnt;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharPointer assign(CharPointer ptr)
|
||||||
|
{
|
||||||
|
seq = ptr.seq;
|
||||||
|
pointer = ptr.pointer;
|
||||||
|
readonly = ptr.readonly;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharPointer ref(int offset)
|
||||||
|
{
|
||||||
|
if (this.equals(INIT))
|
||||||
|
{
|
||||||
|
return INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CharPointer(this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String substring(int len)
|
||||||
|
{
|
||||||
|
if (end())
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return seq.subSequence(pointer, normalize(pointer + len)).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int strlen()
|
||||||
|
{
|
||||||
|
if (end())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = pointer; i < seq.length(); i++)
|
||||||
|
{
|
||||||
|
if (seq.charAt(i) == '\u0000')
|
||||||
|
{
|
||||||
|
return i - pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return seq.length() - pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int strncmp(String str, int len)
|
||||||
|
{
|
||||||
|
if (end())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
String s = seq.subSequence(pointer, normalize(pointer + len)).toString();
|
||||||
|
|
||||||
|
if (len > str.length())
|
||||||
|
{
|
||||||
|
len = str.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.compareTo(str.substring(0, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int strncmp(CharPointer str, int len)
|
||||||
|
{
|
||||||
|
if (end())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
String s = seq.subSequence(pointer, normalize(pointer + len)).toString();
|
||||||
|
|
||||||
|
if (len > str.strlen())
|
||||||
|
{
|
||||||
|
len = str.strlen();
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.compareTo(str.substring(len));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int strnicmp(CharPointer str, int len)
|
||||||
|
{
|
||||||
|
if (end())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
String s = seq.subSequence(pointer, normalize(pointer + len)).toString();
|
||||||
|
|
||||||
|
if (len > str.strlen())
|
||||||
|
{
|
||||||
|
len = str.strlen();
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.compareToIgnoreCase(str.substring(len));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharPointer strchr(char c)
|
||||||
|
{
|
||||||
|
if (end())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String str = seq.subSequence(pointer, pointer + strlen()).toString();
|
||||||
|
int pos = str.indexOf(c);
|
||||||
|
if (pos != -1)
|
||||||
|
{
|
||||||
|
return ref(pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNul()
|
||||||
|
{
|
||||||
|
return charAt() == '\u0000';
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean end()
|
||||||
|
{
|
||||||
|
return end(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean end(int offset)
|
||||||
|
{
|
||||||
|
if (seq == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pointer + offset >= seq.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int OP()
|
||||||
|
{
|
||||||
|
return (int)charAt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharPointer OPERAND()
|
||||||
|
{
|
||||||
|
return ref(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NEXT()
|
||||||
|
{
|
||||||
|
// #define NEXT(p) (((*((p) + 1) & 0377) << 8) + (*((p) + 2) & 0377))
|
||||||
|
return ((((int)seq.charAt(pointer + 1) & 0377) << 8) + ((int)seq.charAt(pointer + 2) & 0377));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int OPERAND_MIN()
|
||||||
|
{
|
||||||
|
// #define OPERAND_MIN(p) (((long)(p)[3] << 24) + ((long)(p)[4] << 16) \
|
||||||
|
// + ((long)(p)[5] << 8) + (long)(p)[6])
|
||||||
|
return (((int)seq.charAt(pointer + 3) << 24) + ((int)seq.charAt(pointer + 4) << 16) +
|
||||||
|
((int)seq.charAt(pointer + 5) << 8) + ((int)seq.charAt(pointer + 6)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int OPERAND_MAX()
|
||||||
|
{
|
||||||
|
return (((int)seq.charAt(pointer + 7) << 24) + ((int)seq.charAt(pointer + 8) << 16) +
|
||||||
|
((int)seq.charAt(pointer + 9) << 8) + ((int)seq.charAt(pointer + 10)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public char OPERAND_CMP()
|
||||||
|
{
|
||||||
|
// #define OPERAND_CMP(p) (p)[7]
|
||||||
|
return seq.charAt(pointer + 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj)
|
||||||
|
{
|
||||||
|
if (obj instanceof CharPointer)
|
||||||
|
{
|
||||||
|
CharPointer ptr = (CharPointer)obj;
|
||||||
|
if (ptr.seq == seq && ptr.pointer == pointer)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int normalize(int pos)
|
||||||
|
{
|
||||||
|
return Math.min(seq.length(), pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return substring(strlen());
|
||||||
|
}
|
||||||
|
|
||||||
|
private CharSequence seq;
|
||||||
|
private int pointer;
|
||||||
|
private boolean readonly = true;
|
||||||
|
}
|
178
src/com/maddyhome/idea/vim/regexp/CharacterClasses.java
Normal file
178
src/com/maddyhome/idea/vim/regexp/CharacterClasses.java
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
package com.maddyhome.idea.vim.regexp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IdeaVim - A Vim emulator plugin for IntelliJ Idea
|
||||||
|
* Copyright (C) 2003 Rick Maddy
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class CharacterClasses
|
||||||
|
{
|
||||||
|
public static final String[] CLASS_NAMES = new String[] {
|
||||||
|
"alnum:]",
|
||||||
|
"alpha:]",
|
||||||
|
"blank:]",
|
||||||
|
"cntrl:]",
|
||||||
|
"digit:]",
|
||||||
|
"graph:]",
|
||||||
|
"lower:]",
|
||||||
|
"print:]",
|
||||||
|
"punct:]",
|
||||||
|
"space:]",
|
||||||
|
"upper:]",
|
||||||
|
"xdigit:]",
|
||||||
|
"tab:]",
|
||||||
|
"return:]",
|
||||||
|
"backspace:]",
|
||||||
|
"escape:]"
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final int RI_DIGIT = 0x01;
|
||||||
|
public static final int RI_HEX = 0x02;
|
||||||
|
public static final int RI_OCTAL = 0x04;
|
||||||
|
public static final int RI_WORD = 0x08;
|
||||||
|
public static final int RI_HEAD = 0x10;
|
||||||
|
public static final int RI_ALPHA = 0x20;
|
||||||
|
public static final int RI_LOWER = 0x40;
|
||||||
|
public static final int RI_UPPER = 0x80;
|
||||||
|
public static final int RI_WHITE = 0x100;
|
||||||
|
|
||||||
|
public static final int CLASS_ALNUM = 0;
|
||||||
|
public static final int CLASS_ALPHA = 1;
|
||||||
|
public static final int CLASS_BLANK = 2;
|
||||||
|
public static final int CLASS_CNTRL = 3;
|
||||||
|
public static final int CLASS_DIGIT = 4;
|
||||||
|
public static final int CLASS_GRAPH = 5;
|
||||||
|
public static final int CLASS_LOWER = 6;
|
||||||
|
public static final int CLASS_PRINT = 7;
|
||||||
|
public static final int CLASS_PUNCT = 8;
|
||||||
|
public static final int CLASS_SPACE = 9;
|
||||||
|
public static final int CLASS_UPPER = 10;
|
||||||
|
public static final int CLASS_XDIGIT = 11;
|
||||||
|
public static final int CLASS_TAB = 12;
|
||||||
|
public static final int CLASS_RETURN = 13;
|
||||||
|
public static final int CLASS_BACKSPACE = 14;
|
||||||
|
public static final int CLASS_ESCAPE = 15;
|
||||||
|
public static final int CLASS_NONE = 99;
|
||||||
|
|
||||||
|
public static boolean isMask(char ch, int mask, int test)
|
||||||
|
{
|
||||||
|
boolean res = false;
|
||||||
|
switch (mask)
|
||||||
|
{
|
||||||
|
case RI_DIGIT:
|
||||||
|
res = isDigit(ch);
|
||||||
|
break;
|
||||||
|
case RI_HEX:
|
||||||
|
res = isHex(ch);
|
||||||
|
break;
|
||||||
|
case RI_OCTAL:
|
||||||
|
res = isOctal(ch);
|
||||||
|
break;
|
||||||
|
case RI_WORD:
|
||||||
|
res = isWord(ch);
|
||||||
|
break;
|
||||||
|
case RI_HEAD:
|
||||||
|
res = isHead(ch);
|
||||||
|
break;
|
||||||
|
case RI_ALPHA:
|
||||||
|
res = isAlpha(ch);
|
||||||
|
break;
|
||||||
|
case RI_LOWER:
|
||||||
|
res = isLower(ch);
|
||||||
|
break;
|
||||||
|
case RI_UPPER:
|
||||||
|
res = isUpper(ch);
|
||||||
|
break;
|
||||||
|
case RI_WHITE:
|
||||||
|
res = isWhite(ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (res == (test > 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDigit(char ch)
|
||||||
|
{
|
||||||
|
return Character.isDigit(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isHex(char ch)
|
||||||
|
{
|
||||||
|
return Character.digit(ch, 16) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isOctal(char ch)
|
||||||
|
{
|
||||||
|
return Character.digit(ch, 8) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isWord(char ch)
|
||||||
|
{
|
||||||
|
return Character.isLetterOrDigit(ch) || ch == '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isHead(char ch)
|
||||||
|
{
|
||||||
|
return Character.isLetter(ch) || ch == '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAlpha(char ch)
|
||||||
|
{
|
||||||
|
return Character.isLetter(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isLower(char ch)
|
||||||
|
{
|
||||||
|
return Character.isLowerCase(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isUpper(char ch)
|
||||||
|
{
|
||||||
|
return Character.isUpperCase(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isWhite(char ch)
|
||||||
|
{
|
||||||
|
return Character.isWhitespace(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isGraph(char ch)
|
||||||
|
{
|
||||||
|
return (ch >= '!' && ch <= '~');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPrint(char ch)
|
||||||
|
{
|
||||||
|
return ((ch >= ' ' && ch <= '~') || ch > 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPunct(char ch)
|
||||||
|
{
|
||||||
|
return ((ch >= '!' && ch <= '/') ||
|
||||||
|
(ch >= ':' && ch <= '@') ||
|
||||||
|
(ch >= '[' && ch <= '\'') ||
|
||||||
|
(ch >= '{' && ch <= '~'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isFile(char ch)
|
||||||
|
{
|
||||||
|
return (isWord(ch) || "/.-+,#$%~=".indexOf(ch) != -1);
|
||||||
|
}
|
||||||
|
}
|
74
src/com/maddyhome/idea/vim/regexp/Flags.java
Normal file
74
src/com/maddyhome/idea/vim/regexp/Flags.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package com.maddyhome.idea.vim.regexp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IdeaVim - A Vim emulator plugin for IntelliJ Idea
|
||||||
|
* Copyright (C) 2003 Rick Maddy
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Flags
|
||||||
|
{
|
||||||
|
public Flags()
|
||||||
|
{
|
||||||
|
flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Flags(int flags)
|
||||||
|
{
|
||||||
|
this.flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int get()
|
||||||
|
{
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSet(int flag)
|
||||||
|
{
|
||||||
|
return ((this.flags & flag) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean allSet(int flags)
|
||||||
|
{
|
||||||
|
return ((this.flags & flags) == flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int init(int flags)
|
||||||
|
{
|
||||||
|
this.flags = flags;
|
||||||
|
|
||||||
|
return this.flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int set(int flags)
|
||||||
|
{
|
||||||
|
this.flags |= flags;
|
||||||
|
|
||||||
|
return this.flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int unset(int flags)
|
||||||
|
{
|
||||||
|
this.flags &= ~flags;
|
||||||
|
|
||||||
|
return this.flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int flags;
|
||||||
|
}
|
125
src/com/maddyhome/idea/vim/regexp/Magic.java
Normal file
125
src/com/maddyhome/idea/vim/regexp/Magic.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package com.maddyhome.idea.vim.regexp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IdeaVim - A Vim emulator plugin for IntelliJ Idea
|
||||||
|
* Copyright (C) 2003 Rick Maddy
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Magic
|
||||||
|
{
|
||||||
|
public static final int AMP = '&' - 256;
|
||||||
|
public static final int AT = '@' - 256;
|
||||||
|
public static final int DOLLAR = '$' - 256;
|
||||||
|
public static final int DOT = '.' - 256;
|
||||||
|
public static final int EQUAL = '=' - 256;
|
||||||
|
public static final int GREATER = '>' - 256;
|
||||||
|
public static final int HAT = '^' - 256;
|
||||||
|
public static final int LBRACE = '[' - 256;
|
||||||
|
public static final int LCURLY = '{' - 256;
|
||||||
|
public static final int LESS = '<' - 256;
|
||||||
|
public static final int LPAREN = '(' - 256;
|
||||||
|
public static final int PERCENT = '%' - 256;
|
||||||
|
public static final int PIPE = '|' - 256;
|
||||||
|
public static final int PLUS = '+' - 256;
|
||||||
|
public static final int QUESTION = '?' - 256;
|
||||||
|
public static final int RPAREN = ')' - 256;
|
||||||
|
public static final int STAR = '*' - 256;
|
||||||
|
public static final int TILDE = '~' - 256;
|
||||||
|
public static final int UNDER = '_' - 256;
|
||||||
|
public static final int N0 = '0' - 256;
|
||||||
|
public static final int N1 = '1' - 256;
|
||||||
|
public static final int N2 = '2' - 256;
|
||||||
|
public static final int N3 = '3' - 256;
|
||||||
|
public static final int N4 = '4' - 256;
|
||||||
|
public static final int N5 = '5' - 256;
|
||||||
|
public static final int N6 = '6' - 256;
|
||||||
|
public static final int N7 = '7' - 256;
|
||||||
|
public static final int N8 = '8' - 256;
|
||||||
|
public static final int N9 = '9' - 256;
|
||||||
|
public static final int a = 'a' - 256;
|
||||||
|
public static final int A = 'A' - 256;
|
||||||
|
public static final int c = 'c' - 256;
|
||||||
|
public static final int C = 'C' - 256;
|
||||||
|
public static final int d = 'd' - 256;
|
||||||
|
public static final int D = 'D' - 256;
|
||||||
|
public static final int f = 'f' - 256;
|
||||||
|
public static final int F = 'F' - 256;
|
||||||
|
public static final int h = 'h' - 256;
|
||||||
|
public static final int H = 'H' - 256;
|
||||||
|
public static final int i = 'i' - 256;
|
||||||
|
public static final int I = 'I' - 256;
|
||||||
|
public static final int k = 'k' - 256;
|
||||||
|
public static final int K = 'K' - 256;
|
||||||
|
public static final int l = 'l' - 256;
|
||||||
|
public static final int L = 'L' - 256;
|
||||||
|
public static final int m = 'm' - 256;
|
||||||
|
public static final int M = 'M' - 256;
|
||||||
|
public static final int n = 'n' - 256;
|
||||||
|
public static final int N = 'N' - 256;
|
||||||
|
public static final int o = 'o' - 256;
|
||||||
|
public static final int O = 'O' - 256;
|
||||||
|
public static final int p = 'p' - 256;
|
||||||
|
public static final int P = 'P' - 256;
|
||||||
|
public static final int s = 's' - 256;
|
||||||
|
public static final int S = 'S' - 256;
|
||||||
|
public static final int u = 'u' - 256;
|
||||||
|
public static final int U = 'U' - 256;
|
||||||
|
public static final int v = 'v' - 256;
|
||||||
|
public static final int V = 'V' - 256;
|
||||||
|
public static final int w = 'w' - 256;
|
||||||
|
public static final int W = 'W' - 256;
|
||||||
|
public static final int x = 'x' - 256;
|
||||||
|
public static final int X = 'X' - 256;
|
||||||
|
public static final int z = 'z' - 256;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Magic characters have a special meaning, they don't match literally.
|
||||||
|
* Magic characters are negative. This separates them from literal characters
|
||||||
|
* (possibly multi-byte). Only ASCII characters can be Magic.
|
||||||
|
*/
|
||||||
|
public static int Magic(int x)
|
||||||
|
{
|
||||||
|
return (x - 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int un_Magic(int x)
|
||||||
|
{
|
||||||
|
return (x + 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean is_Magic(int x)
|
||||||
|
{
|
||||||
|
return (x < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int no_Magic(int x)
|
||||||
|
{
|
||||||
|
if (is_Magic(x))
|
||||||
|
return un_Magic(x);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toggle_Magic(int x)
|
||||||
|
{
|
||||||
|
if (is_Magic(x))
|
||||||
|
return un_Magic(x);
|
||||||
|
return Magic(x);
|
||||||
|
}
|
||||||
|
}
|
5461
src/com/maddyhome/idea/vim/regexp/RegExp.java
Normal file
5461
src/com/maddyhome/idea/vim/regexp/RegExp.java
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user