Full Code of dajva/rg.el for AI

master a614e7d7709c cached
45 files
405.9 KB
103.7k tokens
19 symbols
1 requests
Download .txt
Showing preview only (423K chars total). Download the full file or copy to clipboard to get everything.
Repository: dajva/rg.el
Branch: master
Commit: a614e7d7709c
Files: 45
Total size: 405.9 KB

Directory structure:
gitextract_p8leny0j/

├── .ert-runner
├── .github/
│   └── workflows/
│       ├── build.yml
│       └── documentation.yml
├── .gitignore
├── Cask
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── docs/
│   ├── configuration.org
│   ├── contribute.org
│   ├── gpl.org
│   ├── index.org
│   ├── org-bootstrap.el
│   ├── rst/
│   │   ├── Makefile
│   │   ├── conf.py
│   │   └── elispdomain.py
│   ├── usage.org
│   └── utils.org
├── rg-header.el
├── rg-history.el
├── rg-ibuffer.el
├── rg-info-hack.el
├── rg-isearch.el
├── rg-menu.el
├── rg-result.el
├── rg.el
├── rgel.info
├── test/
│   ├── data/
│   │   ├── bar.baz
│   │   ├── bar.el
│   │   ├── context.el
│   │   ├── dirlocals/
│   │   │   └── .dir-locals.el
│   │   ├── foo.baz
│   │   ├── foo.el
│   │   └── limenu.el
│   ├── package-bootstrap.el
│   ├── rg-header.el-test.el
│   ├── rg-history.el-test.el
│   ├── rg-isearch.el-test.el
│   ├── rg-menu.el-test.el
│   ├── rg.el-test.el
│   ├── style-check.el
│   ├── test-helper.el
│   └── wgrep-rg.el-test.el
└── wgrep-rg.el

================================================
FILE CONTENTS
================================================

================================================
FILE: .ert-runner
================================================
-L .


================================================
FILE: .github/workflows/build.yml
================================================
name: Build
on:
  push:
  release:
    types:
      - created
  pull_request:
  schedule:
    - cron: '0 6 1 * *'
jobs:
  tests:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        emacs_version:
          - 28.1
          - 28.2
          - 29.1
          - 29.4
          - 30.1
          - 30.2
    steps:
    - name: Setup emacs-ci-nix for ${{ matrix.emacs_version }}
      uses: purcell/setup-emacs@master
      with:
        version: ${{ matrix.emacs_version }}

    - name: Setup Cask
      uses: conao3/setup-cask@master

    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Install ripgrep
      env:
        REPO: BurntSushi/ripgrep
      run: |
        RELEASE_TAG=$(curl -sL --fail \
        -H 'Accept: application/vnd.github.v3+json' \
        -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
        'https://api.github.com/repos/BurntSushi/ripgrep/releases/latest' \
        | jq -r '.name')

        PACKAGE_NAME=ripgrep-${RELEASE_TAG}-x86_64-unknown-linux-musl.tar.gz

        curl -sL --fail  \
        -H "Accept: application/vnd.github.v3+json" \
        -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
        "https://api.github.com/repos/${REPO}/releases/tags/${RELEASE_TAG}" \
        | jq -r ".assets | .[] | select(.name==\"${PACKAGE_NAME}\") | .url" \
        | tee asset.url

        curl -sL --fail \
        -H "Accept: application/octet-stream" \
        -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
        -o "${PACKAGE_NAME}" \
        "$(cat asset.url)"
        tar xf ${PACKAGE_NAME}
        echo "$PWD/$(basename -s .tar.gz $PACKAGE_NAME)" >> $GITHUB_PATH

    - name: Install emacs deps
      run: make EMACS_VERSION=${{ matrix.emacs_version }} deps

    - name: Run tests
      run: |
        emacs --version
        rg --version
        make EMACS_VERSION=${{ matrix.emacs_version }} test

    - name: Coveralls
      uses: coverallsapp/github-action@master
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        flag-name: emacs-${{ matrix.emacs_version }}
        parallel: true

  finish:
    needs: tests
    runs-on: ubuntu-latest
    steps:
    - name: Coveralls Finished
      uses: coverallsapp/github-action@master
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        parallel-finished: true



================================================
FILE: .github/workflows/documentation.yml
================================================
name: Documentation
on:
  push:
  release:
    types:
      - created
jobs:
  documentation:
    runs-on: ubuntu-latest
    steps:
    - name: Setup emacs-ci-nix for emacs 28.1
      uses: purcell/setup-emacs@master
      with:
        version: 28.1

    - name: Setup Cask
      uses: conao3/setup-cask@master

    - name: Install sphinx
      run: sudo apt-get --yes install python3-sphinx

    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Install emacs deps
      run: make deps

    - name: Changed files
      id: files
      uses: jitterbit/get-changed-files@v1
      continue-on-error: true

    - name: Extract ref
      id: extract_ref
      run: echo ::set-output name=ref::${GITHUB_REF#refs/*/}

    - name: Generate info documentation
      if:  github.event_name != 'release' && contains(steps.files.outputs.all, 'docs/')
      run: |
        make info
        git config user.name "GitHub Actions Bot"
        git config user.email "<>"
        git add rgel.info
        git commit -m 'Generate info documentation'
        git push
        # Clean to avoid pushing build artifacts in the steps below
        make clean-docs

    - name: Generate restructured text
      run:  make rst

    - name: Set documentation branch
      id: doc_branch
      run: |
        if [[ ${{ github.event_name }} = "release" ]]; then
          echo ::set-output name=branch::release
        else
          echo ::set-output name=branch::master
        fi

    - name: Deploy to branch ${{ steps.doc_branch.outputs.branch }}
      if: github.ref == 'refs/heads/master' || github.event_name == 'release'
      uses: JamesIves/github-pages-deploy-action@v4.6.4
      with:
        branch: ${{ steps.doc_branch.outputs.branch }}
        folder: docs/rst
        repository-name: dajva/rg.el-docs
        token: ${{ secrets.DOCUMENTATION_DEPLOYMENT }}

    - name: Tag release ${{ steps.extract_ref.outputs.ref }}
      if: github.event_name == 'release'
      env:
        RELEASE_VERSION: ${{ steps.extract_ref.outputs.ref }}
        DOCUMENTATION_DEPLOYMENT: ${{ secrets.DOCUMENTATION_DEPLOYMENT }}
      run: |
        git clone https://github.com/dajva/rg.el-docs
        cd rg.el-docs
        git checkout release
        git tag $RELEASE_VERSION
        git push https://x-access-token:${DOCUMENTATION_DEPLOYMENT}@github.com/dajva/rg.el-docs $RELEASE_VERSION


================================================
FILE: .gitignore
================================================
.cask/*
dist/*
*.elc


================================================
FILE: Cask
================================================
(source gnu)
(source melpa)

(package-file "rg.el")

(files
 "rg.el"
 "rg-history.el"
 "rg-result.el"
 "rg-header.el"
 "rg-ibuffer.el"
 "rg-info-hack.el"
 "rg-isearch.el"
 "rg-menu.el"
 "wgrep-rg.el")

(development
 (depends-on "cl-lib" "0.5")
 (depends-on "find-file-in-project")
 (depends-on "flycheck")
 (depends-on "package-lint")
 (depends-on "s")
 (depends-on "seq")
 (depends-on "transient")
 (depends-on "undercover")
 (depends-on "wgrep")
 (depends-on "ox-rst" :git "https://github.com/dajva/ox-rst"))


================================================
FILE: Dockerfile
================================================
FROM ubuntu
SHELL ["/bin/bash", "-c"]

RUN apt-get -y update

# noninteractive is needed to avoid config of tzlocal package
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install curl xz-utils make git python3 ripgrep sudo python3-sphinx python3-sphinx-rtd-theme texinfo

RUN install -d -m755 -o $(id ubuntu -u) -g $(id ubuntu -g) /nix
USER ubuntu
ENV USER ubuntu
WORKDIR /home/ubuntu

# Install nix
RUN curl -L https://nixos.org/nix/install | sh

# Install cachix
RUN . ~/.nix-profile/etc/profile.d/nix.sh && \
    nix-env -iA cachix -f https://cachix.org/api/v1/install

# Install emacs from nix-emacs-ci
ARG EMACS_VERSION=28-2
RUN . ~/.nix-profile/etc/profile.d/nix.sh && \
    cachix use emacs-ci && \
    nix-env -iA emacs-${EMACS_VERSION} -f https://github.com/purcell/nix-emacs-ci/archive/master.tar.gz && \
    emacs --version

# Install cask
RUN . ~/.nix-profile/etc/profile.d/nix.sh && \
    curl -fsSL https://raw.githubusercontent.com/cask/cask/master/go | python3

ENV PATH=/home/ubuntu/.cask/bin:$PATH
ENTRYPOINT ["bash", "-c", "source ~/.nix-profile/etc/profile.d/nix.sh && \"$@\"", "-s"]


================================================
FILE: LICENSE
================================================
                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, 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
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If 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 convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU 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
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state 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 program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    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 3 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, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

    <program>  Copyright (C) <year>  <name of author>
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.

  The GNU General Public License does not permit incorporating your program
into proprietary programs.  If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.  But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.


================================================
FILE: Makefile
================================================
EMACS_VERSION=29-4
DOCKER_IMAGE=rg.el-test-emacs-$(EMACS_VERSION)

ifdef USE_DOCKER
DOCKER_WRAPPER=docker run --workdir /app --mount type=bind,source="$(PWD)",target=/app $(DOCKER_IMAGE)
%: run_make
	@:

.PHONY: run_make
run_make:
	$(DOCKER_WRAPPER) $(MAKE) EMACS_VERSION=$(EMACS_VERSION) $(MAKECMDGOALS)

else  # actual Makefile

PKG_NAME = $(shell cask info | head -1 | cut -f2 -d" ")
PKG_VERSION = $(shell cask version)
PKG_FULL_NAME = $(PKG_NAME)-$(PKG_VERSION)
SOURCES = $(shell cask files)
OBJECTS = $(SOURCES:.el=.elc)
STYLE_CHECK= -L test -L . -l test/style-check.el
DISABLE_DEFALIAS_CHECK= --eval "(defun package-lint--check-defalias (prefix def))"

# This setup testing similar to ert-runner for legacy reasons.
# All files under test/ that matches the source files.
TEST_FILES = $(filter $(patsubst %,test/%-test.el, $(SOURCES)), $(wildcard test/*.el))
# Load test-helper.el first, then all test files.
LOAD_TEST_FILES = -L test -l test-helper $(patsubst %,-l %,$(TEST_FILES:test/%.el=%))

SPHINX-BUILD = sphinx-build
DOC_DIR = docs
ORG_DOCS= $(wildcard $(DOC_DIR)/*.org)
RST_OUT_DIR = $(DOC_DIR)/rst
RST_DOCS = $(addprefix $(RST_OUT_DIR)/,$(patsubst %.org,%.rst,$(notdir $(ORG_DOCS))))

all: deps test

docker-build:
	docker build --build-arg EMACS_VERSION=$(EMACS_VERSION) -t $(DOCKER_IMAGE) .

test: ert-test style-check package-lint build-test package-test

build-test: clean build
	cask clean-elc

$(RST_DOCS): | $(RST_OUT_DIR)

$(RST_OUT_DIR):
	mkdir $(RST_OUT_DIR)

$(RST_OUT_DIR)/%.rst: docs/%.org
	RST_OUT_DIR=$(abspath $(RST_OUT_DIR)) cask emacs --batch -Q -L . -l docs/org-bootstrap.el $< --funcall rg-export-to-rst

rst: $(RST_DOCS)

html: rst
	$(SPHINX-BUILD) -b html $(RST_OUT_DIR) $(RST_OUT_DIR)/_build/html

info: rst
	$(SPHINX-BUILD) -b texinfo $(RST_OUT_DIR) $(RST_OUT_DIR)/_build/info
	make -C $(RST_OUT_DIR)/_build/info
	cp $(RST_OUT_DIR)/_build/info/rgel.info .

docs: html

clean-docs:
	rm $(RST_OUT_DIR)/*.rst
	make -C $(RST_OUT_DIR) clean

clean:
	cask clean-elc

build: $(OBJECTS)

%.elc: %.el
	cask emacs -batch -Q -L . -eval "(progn (setq byte-compile-error-on-warn t) (batch-byte-compile))" $<

package-test:
	-@rm -r dist 2> /dev/null || true
	-@rm -r /tmp/$(PKG_FULL_NAME)-elpa 2> /dev/null || true
	cask package
	PKG_FULL_NAME=$(PKG_FULL_NAME) emacs -batch -Q -l test/package-bootstrap.el \
		--eval "(progn (package-install-file (expand-file-name \"dist/$(PKG_FULL_NAME).tar\")) (rg \"rg\" \"elisp\" \"/tmp/$(PKG_FULL_NAME)-elpa\"))"

style-check:
	cask emacs -batch -Q $(STYLE_CHECK) -f run-emacs-lisp-flycheck-and-exit $(SOURCES)
package-lint:
	cask emacs -batch -Q $(STYLE_CHECK) $(DISABLE_DEFALIAS_CHECK) -f run-package-lint-and-exit rg.el


unit-test:
	cask emacs --batch -l ert $(LOAD_TEST_FILES) --eval="(ert-run-tests-batch-and-exit \"rg-unit\")"

integration-test:
	cask emacs --batch -l ert $(LOAD_TEST_FILES) --eval="(ert-run-tests-batch-and-exit \"rg-integration\")"

ert-test:
	cask emacs --batch -l ert $(LOAD_TEST_FILES) -f ert-run-tests-batch-and-exit

deps:
	cask install


.PHONY: all test build-test clean clean-docs package-test style-check package-lint unit-test integration-test ert-test deps deps_execute deps_prepare deps_cleanup docs

endif


================================================
FILE: README.md
================================================
# rg.el

[![License GPL 3](https://img.shields.io/badge/license-GPL_3-green.svg?style=flat)](LICENSE)
[![MELPA Stable](https://stable.melpa.org/packages/rg-badge.svg)](https://stable.melpa.org/#/rg)
[![MELPA](http://melpa.org/packages/rg-badge.svg)](http://melpa.org/#/rg)
[![Build Status](https://github.com/dajva/rg.el/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/dajva/rg.el/actions/workflows/build.yml)
[![Coverage Status](https://coveralls.io/repos/github/dajva/rg.el/badge.svg)](https://coveralls.io/github/dajva/rg.el)

Use [ripgrep](https://github.com/BurntSushi/ripgrep) in Emacs.

Ripgrep is a replacement for both grep like (search one file) and ag
like (search many files) tools. It's fast and versatile and written in
Rust. For some introduction and benchmarks, see
[ripgrep is faster than {grep, ag, git grep, ucg, pt, sift}](http://blog.burntsushi.net/ripgrep/).

![screenshot](screenshot.png)

## Installation

This package is available on
[MELPA Stable](https://stable.melpa.org/#/rg) and
[MELPA](http://melpa.org/#/rg). Install with `M-x package-install`
<kbd>RET</kbd> `rg` from within Emacs.

It is also available in GNU Guix as
[emacs-rg](https://guix.gnu.org/en/packages/emacs-rg-2.2.0/).  Install
with `guix package -i emacs-rg`.

If you want to install manually just put `rg.el` and the rest of the
elisp files somewhere in your load path and add require the package:

``` el
(require 'rg)
```

`rg` and friends are autoloaded symbols which means it's also possible
to defer loading if you have autoloading setup.

### Setup key bindings
This will setup the default key bindings in a non lazy way. If you
care about startup performance see the next example.

``` el
(rg-enable-default-bindings)
```

See
[documentation](https://rgel.readthedocs.io) for how to handle lazy loading.


### Use old defaults
`rg.el` 2.0.0 will use new default settings to improve look and feel,
more consistent key bindings etc. If you want to use the old defaults
add this to your `init.el`:

``` el
(rg-use-old-defaults)
```

### rg-menu

If you prefer to use a [magit](https://github.com/magit/magit) like
interface as a complement to regular key maps, replace
`(rg-enable-default-bindings)` with `(rg-enable-menu)`. The menus are
built with [transient](https://github.com/magit/transient), which
means that the menus can be modified in the same way as in magit.

## Documentation
Info documentation is included in the package.
Online documentation: https://rgel.readthedocs.io

## Contribute

- Install [cask](http://cask.github.io/).
- Install dependencies:

``` Shell
make deps
```
- Run tests:

``` Shell
make test
```


## License

See [LICENSE](LICENSE).


================================================
FILE: docs/configuration.org
================================================
#+TITLE: Configuration
#+AUTHOR: David Landell
#+EMAIL: david.landell@sunnyhill.email
#+DATE: 2019
#+LANGUAGE: en
#+OPTIONS: broken-links:auto, toc:nil, email:nil, num:nil, ^:nil, author:nil, date:nil

#+INCLUDE: "utils.org"

* Customization
  :PROPERTIES:
  :CUSTOM_ID: customization
  :END:
  Customization is done via the Emacs customization system. The group
  =rg= is the main group of the package.
  #+BEGIN_SRC elisp
  M-x customize-group [RET] rg [RET]
  #+END_SRC
  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-executable '(executable-find "rg"))
  #+END_SRC

  The /ripgrep/ executable to use. Could be an absolute path or just the
  base name if the executable is in the path. The default is using
  =executable-find= to locate the command. If you want to use this
  package with tramp it might be better to set it to just "rg" in
  order to let the OS find the binary where it's invoked.
  From Emacs 27.1, the tramp use case is by default handled
  automatically. See [[opt:rg-executable-per-connection]] for details.
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-executable-per-connection)
  #+END_SRC

  This setting only has effect in Emacs 27.1 or later.
  Handle the [[opt:rg-executable]] automatically for different hosts if used
  with tramp. =executable-find= for "rg" binary will be invoked on
  remote hosts to determine the path to ripgrep. The result is stored
  per connection.
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-custom-type-aliases)
  #+END_SRC

  An association list that maps file type aliases to a space
  delimited string with file globs. These are combined with the
  /ripgrep/ builtin file aliases.

  Example:
  #+BEGIN_SRC elisp
    (setq rg-custom-type-aliases
      '(("foo" .    "*.foo *.bar")
        ("baz" .    "*.baz *.qux")))
  #+END_SRC

  You may also add lambdas to =rg-custom-type-aliases= to add aliases
  dynamically based on mode, directory, project, etc.

  #+BEGIN_SRC elisp
     (add-to-list
      'rg-custom-type-aliases
      (lambda ()
        (when (in-frontend-app)
          (cons "ui" "*.js *.hbs *.json"))))
  #+END_SRC
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-prioritized-type-aliases)
  #+END_SRC

  A list of aliases that are prioritized among ripgrep's builtin
  aliases when selecting the alias based on the buffer file name. This
  list contains only the alias names and the order between the items
  does not matter.

  Example:
  #+BEGIN_SRC elisp
    (setq rg-custom-type-aliases
      '("cpp" "puppet"))
  #+END_SRC
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-default-alias-fallback)
  #+END_SRC

  This setting controls the default alias used when no alias can be
  recognized for the current buffer. =all= or =everything= are
  reasonable values for this variable.
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-command-line-flags)
  #+END_SRC

  A list of command line flags that will be appended to the
  /ripgrep/ command line. Must either be a list of flags or a function
  that returns a list of flags.
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-group-result)
  #+END_SRC


  Controls the layout of the results buffer. If non =nil=, each file name
  is displayed once and matches are grouped under that filename instead of
  repeating the filename on each match. This is essentially the layout of
  the =--no-heading= /ripgrep/ command line flag.
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-show-columns)
  #+END_SRC


  Controls if column numbers are used in the search result.
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-ignore-case)
  #+END_SRC

  Setting that controls if case sensitive search is made or not. It
  can essentially be *on*, *off* or *smart*. The *smart* setting will
  trigger an analyze of the search string and if it's all lower case,
  the search will be case /insensitive/, otherwise it will be case
  /sensitive/. The following values are valid:

  - *case-fold-search* - A non nil value of =case-fold-search= will trigger smart case behavior.
  - *smart* - Smart case behavior.
  - *force* - Always ignore case.
  - *nil* - Always consider case.
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-hide-command)
  #+END_SRC

  Hide most of command line by default. This is enabled by default and can
  be set to =nil= to show full command line.
  This can be toggled in the results buffer by clicking on the command line.
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-keymap-prefix)
  #+END_SRC

  This variable sets the default prefix used for the global key bindings.
  Note that =rg-enable-default-bindings= needs to be invoked for the
  bindings to be enabled.
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-use-transient-menu)
  #+END_SRC

  Controls whether =rg-menu= will be used by default or not. It's also
  possible to enable the menu explicitly with
  #+BEGIN_SRC elisp
  (rg-enable-menu)
  #+END_SRC
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-show-header)
  #+END_SRC

  Controls if the search info header is shown in the result buffer. This
  is enabled by default but can be disabled by setting this variable to
  =nil=.
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-buffer-name)
  #+END_SRC

  Controls the name of the results buffer. It may be /string/ or /function/.
  This name will be surrounded by  =*= to yield the final buffer name
  so if this setting is =foo= the buffer name will be =*foo*=.
  One useful case of using it is to have separate result buffers per project.
  One can set this variable in `dir-locals` file or set it to function.

  Example, this function will set results buffer name based on `project-current`:
  #+BEGIN_SRC elisp
    (defun my-rg-buffer-name ()
      (let ((p (project-current)))
        (if p
            (format "rg %s" (abbreviate-file-name (cdr p)))
          "rg")))
  #+END_SRC
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-ignore-ripgreprc)
  #+END_SRC

  Controls if the [[https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md#configuration-file][ripgreprc]] file should be ignored or not. If =nil=,
  the config file will be used, otherwise it will be ignored. The
  default is to ignore this file in order to avoid that conflicting
  settings have impact on this package's behavior. Setting this to =nil=
  may affect core functionality of this package. Especially changing
  colors can affect parsing of the output and result in a broken
  results buffer.
  :END:

*** Position numbers alignment
    :PROPERTIES:
    :CUSTOM_ID: position-numbers-alignment
    :END:

    When operating /rg/ in grouped output mode ([[opt:rg-group-result]] is non
    nil), it's possible to control how the line and column numbers are
    displayed in the result buffer.

    Example settings:

    #+BEGIN_SRC elisp
    (setq rg-align-position-numbers t)
    (setq rg-align-line-number-field-length 3)
    (setq rg-align-column-number-field-length 3)
    (setq rg-align-line-column-separator "#")
    (setq rg-align-position-content-separator "|")
    #+END_SRC

    Will yield the following format:

    #+BEGIN_EXAMPLE
    File: matched_file.foo
      1#  2|match1
    888# 10|match2
    #+END_EXAMPLE

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-custom-info 'rg-align-position-numbers)
    #+END_SRC

    Setting this to =t= will align line and column numbers in columns padded
    with white space.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-custom-info 'rg-align-line-number-field-length)
    #+END_SRC


    Defines the length of the line number field.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-custom-info 'rg-align-column-number-field-length)
    #+END_SRC


    Defines the length of the column number field.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-custom-info 'rg-align-line-column-separator)
    #+END_SRC


    Separator string used between line and column numbers. =nil= means
    use default separator from /ripgrep/.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-custom-info 'rg-align-position-content-separator)
    #+END_SRC

    Separator string used between the position numbers and matched content. =nil= means
    use default separator from /ripgrep/.
    :END:

* Faces
  All faces are in the subgroup =rg-face= of the main group =rg=.
  #+BEGIN_SRC elisp
  M-x customize-group [RET] rg-face [RET]
  #+END_SRC
*** Results buffer
    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
  (rg-face-info 'rg-match-face)
    #+END_SRC
    Face used to highlight matches in result.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
  (rg-face-info 'rg-error-face)
    #+END_SRC
    Face used to highlight errors when invoking /ripgrep/.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
  (rg-face-info 'rg-context-face)
    #+END_SRC
    Face used to highlight context lines in /ripgrep/ output when
    =--context-lines= flag is used.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
  (rg-face-info 'rg-info-face)
    #+END_SRC
    Face used to highlight general info in results buffer. For instance
    the number of matches found.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
  (rg-face-info 'rg-warning-face)
    #+END_SRC
    Face used to highlight warnings in the /ripgrep/ output.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
  (rg-face-info 'rg-filename-face)
    #+END_SRC
    Face used to highlight filenames in the output.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
  (rg-face-info 'rg-file-tag-face)
    #+END_SRC
    Face used for the =File:= tag in grouped results output.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
  (rg-face-info 'rg-line-number-face)
    #+END_SRC
    Face used on line numbers.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
  (rg-face-info 'rg-column-number-face)
    #+END_SRC
    Face used on column numbers.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
  (rg-face-info 'rg-match-position-face)
    #+END_SRC
    Face added to file positions. This is the start of a matching line
    and depending on configuration may be, file name, column number and
    line number.
    :END:


*** Header line
    :PROPERTIES:
    :CUSTOM_ID: header_line_config
    :END:
    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-face-info 'rg-toggle-on-face)
    #+END_SRC
    Face used for flags that are toggled =on=.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
   (rg-face-info 'rg-toggle-off-face)
    #+END_SRC
    Face used for flags that are toggled =off=.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-face-info 'rg-literal-face)
    #+END_SRC
    Face used the on the =literal= marker in the header line.
    :END:

    :OPTION:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-face-info 'rg-regexp-face)
    #+END_SRC
    Face used the on the =regexp= marker in the header line.
    :END:

* Configuration functions
  :PROPERTIES:
  :CUSTOM_ID: configuration_functions
  :END:

  :FUNCTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-function-info 'rg-enable-default-bindings)
  #+END_SRC
  Enable the default keyboard bindings for the package with prefix
  key. If [[opt:rg-use-transient-menu]] is on this will enable the menu
  instead of activating the global bindings. If =prefix= is not
  provided [[opt:rg-keymap-prefix]] will be used.
  :END:

  :FUNCTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-function-info 'rg-enable-menu)
  #+END_SRC
  Enable the [[file:usage.org::#the_menu][rg-menu]] with prefix key. This bypass
  [[opt:rg-use-transient-menu]] setting. If =prefix= is not provided
  [[opt:rg-keymap-prefix]] will be used.
  :END:

  :FUNCTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-function-info 'rg-use-old-defaults)
  #+END_SRC
  This function is provided to keep backwards compatibility with
  versions older than 2.0.0. In this version default settings as well
  as key bindings changed and to bring back the old defaults call this
  function in your init file.
  :END:

* Hooks
  :PROPERTIES:
  :CUSTOM_ID: hooks
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-finish-functions)
  #+END_SRC
  Functions to call when a ripgrep search is finished.

  Each function is called with two arguments: the compilation buffer,
  and a string describing how the process finished.
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-filter-hook)
  #+END_SRC
  Hook run after new content has been inserted in in the rg buffer.
  This hook is called every time the rg buffer has been updated with
  new content and filtered internally by the package.
  :END:

  :OPTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-custom-info 'rg-mode-hook)
  #+END_SRC
  Hook run after entering rg mode.
  :END:

* Configuration macros
  :PROPERTIES:
  :CUSTOM_ID: configuration_macros
  :END:

  :FUNCTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-function-info 'rg-define-toggle)
  #+END_SRC

  This is a macro that can be used to define custom /ripgrep/ flag
  toggling functions in the result buffer. The macro takes the flag
  (and potential value) as an argument and optionally binds the toggle
  function to a key. If =default= is non nil the flag is used by default.

  The function defined by this macro will be named as the flag name
  stripped with leading dashes and prefixed with =rg-custom-toggle-flag-=.

  #+BEGIN_SRC elisp
    (rg-define-toggle "-uu" "I" t)
  #+END_SRC

  Creates a function named =rg-custom-toggle-flag-uu= that is on by
  default and bound to =I= in /rg/ result
  buffer.

  #+BEGIN_SRC elisp
    (rg-define-toggle "--context 3" (kbd "C-c c"))
  #+END_SRC

  Creates a function named =rg-custom-toggle-flag-context= that is off by
  default and bound to =C-c c= in /rg/ result
  buffer.
  :END:

  :FUNCTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-function-info 'rg-define-search)
  #+END_SRC

  This macro can be used to define custom search functions in a
  declarative style. Default implementations for common behavior is
  available and custom forms can also be used.

  It optionally starts with a string that is used as the docstring for
  the defined function.  The rest of the arguments contain key value pairs
  according to the specification below.  All keys are optional with
  specified default if left out.

  - *:query* - Method for retrieving the search string.  Allowed values are
    =point= which means extract thing at point and =ask= which means
    prompt the user for a string.  Any form that evaluates to a string
    is allowed. Default is =ask=.
  - *:format* - Specifies if =:query= is interpreted literally
    (=literal=) or as a regexp (=regexp=). If it is a form, eg.
    =(not current-prefix-arg)=, and is non-nil the =:query= is interpreted
    literally, otherwise as a regexp. Default is =regexp=.
  - *:files* - Form that evaluates to a file alias or custom file
    glob. =current= means extract alias from current buffer file name,
    =ask= will prompt the user. Default is =ask=.
  - *:dir* - Root search directory.  Allowed values are =ask= for user
    prompt, =current= for current dir and =project= for project
    root.  Any form that evaluates to a directory string is also allowed.
    Default is =ask=.
  - *:confirm* - =never=, =always=, or =prefix= are allowed values.  Specifies
    if the the final search command line string can be modified
    and confirmed the user. Default is =never=.
  - *:flags* - =ask= or a list of command line flags that will be used when
    invoking the search.
  - *:menu* - Bind the command into =rg-menu=.  Must be a list with three
    items in it.  The first item is the description of the
    group in which the new command will appear.  If the group
    does not exist a new will be created.  The second item is
    the key binding for this new command (ether a key vector
    or a key description string) and the third item is the
    description of the command that will appear in the menu.

  Examples:
  #+BEGIN_SRC elisp
    (rg-define-search search-everything-at-home
      "Search files including hidden in home directory"
      :query ask
      :format literal
      :files "everything"
      :flags ("--hidden")
      :dir (getenv "HOME")
      :menu ("Search" "h" "Home"))

    (rg-define-search rg-emacs
      "Search the emacs lisp source code."
      :dir "/usr/share/emacs/25.2/lisp/"
      :flags '("-z")
      :files "*.{el,el.gz}"
      :menu ("Custom" "L" "lisp"))
  #+END_SRC
  :END:

* Use with evil-mode
  Some key bindings clash with /evil-mode/. Recommendation is to use
  evil /motion/ state for the results buffer and then switch to
  evil /normal/ mode when editing in /wgrep-mode/. Some adjustments
  need to be done to avoid the clashes though.

  This is a start of a configuration. This let /rg-mode/'s key bindings
  override the motion state map bindings based on that these motion
  keys are not important in an /rg/ results buffer.
  Adjust this to your preferred use case:
  #+begin_src elisp
    (with-eval-after-load 'rg
      (advice-add 'wgrep-change-to-wgrep-mode :after
                  #'evil-normal-state)
      (advice-add 'wgrep-to-original-mode :after
                  #'evil-motion-state)
      (defvar rg-mode-map)
      (add-to-list 'evil-motion-state-modes 'rg-mode)
      (evil-add-hjkl-bindings rg-mode-map 'motion
        "e" #'wgrep-change-to-wgrep-mode
        "g" #'rg-recompile
        "t" #'rg-rerun-change-literal))
  #+end_src

* Customizing the menu
  :PROPERTIES:
  :CUSTOM_ID: customizing_the_menu
  :END:
  The menu can be modified from the emacs configuration file.

  To add a new *switch* before the option triggered by =-n= at suffix
  level 3:
  #+BEGIN_SRC elisp
    (transient-insert-suffix 'rg-menu "-n" '(3 "-o" "Only print matches" "--only-matching"))
  #+END_SRC
  To add a new *option* before the option triggered by =-g= at suffix
  level 4:
  #+BEGIN_SRC elisp
    (transient-insert-suffix 'rg-menu "-g" '(4 "-f" "Pattern file" "--file="))
  #+END_SRC
  The === in =--file== triggers argument input for the flag.

  To remove an item from the menu specify the trigger key in the
  transient remove command.
  For example, to remove the =Search hidden files= switch use the following:
  #+BEGIN_SRC elisp
    (transient-remove-suffix 'rg-menu "-h")
  #+END_SRC

  Please refer to the [[https://magit.vc/manual/transient/Modifying-Existing-Transients.html#Modifying-Existing-Transients][transient]] documentation for details on customizing the menu.

  This package also adds a convenience function for appending new
  *commands* to the menu in the groups at the bottom.

  :FUNCTION:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-function-info 'rg-menu-transient-insert)
  #+END_SRC
  This inserts a new command under =group= if it exists, otherwise a
  new group is created. =key=, =description= and =command= is as for
  the =transient-insert-suffix= function.

  For example to insert a new command under =Search= group:
  #+BEGIN_SRC elisp
    (rg-menu-transient-insert "Search" "m" "My search" 'my-search-command)
  #+END_SRC

  It's usually better to use the =:menu= key of the [[func:rg-define-search]]
  macro to define a search function and adding it to the menu in one go.
  :END:



================================================
FILE: docs/contribute.org
================================================
#+TITLE: Contribute
#+AUTHOR: David Landell
#+EMAIL: david.landell@sunnyhill.email
#+DATE: 2019
#+LANGUAGE: en
#+OPTIONS: broken-links:auto, toc:nil, email:nil, num:nil, ^:nil, author:nil, date:nil

#+INCLUDE: "utils.org"

Contributions are very welcome. Development is done in the [[https://github.com/dajva/rg.el][GitHub
repository]]. If you find a bug, please report it in the [[https://github.com/dajva/rg.el/issues][issue tracker]].


* Pull requests
  :PROPERTIES:
  :CUSTOM_ID: pull_requests
  :END:
  If you want to submit a patch, please submit a [[https://github.com/dajva/rg.el/pulls][GitHub pull
  request]]. If you want to submit any larger code changes, please create an
  issue first for discussion. Some features does not fit well into
  this package and there is also good to agree on the general design
  before doing any major work.

  The minimum requirements for a pull request to be accepted is that
  all existing tests pass and test coverage should not decrease. Often
  a patch also needs additional tests, new/changed documentation etc.

  Don't strive to submit a perfect pull request directly. It's often
  better to submit something simple that shows the main direction of
  the new code in order to discuss the best way to proceed and what
  additions are needed.

* Docker
  :PROPERTIES:
  :CUSTOM_ID: docker
  :END:
  Docker can be used to run the tests or generate documentation
  locally without installing dependencies on the host and to test with
  different emacs versions.

  To use docker, just set the =USE_DOCKER= variable when
  running the tests.
  The =EMACS_VERSION= variable can be used to select emacs
  version. Note that dash ('-') is used instead of points ('.') in the
  version numbering. So emacs 28.2 is specified as =28-2=.
  Emacs are installed from https://github.com/purcell/nix-emacs-ci so
  only emacs versions supported in that repository will work.
  - Build docker container:
    #+begin_src bash
      # Don't use the USE_DOCKER variable here
      make EMACS_VERSION=30-2 docker-build
    #+end_src
  - To run all the tests in docker image:
    #+begin_src bash
     make USE_DOCKER=true test
    #+end_src
  - Use a specific emacs version:
    #+begin_src bash
      make USE_DOCKER=true EMACS_VERSION=snapshot
    #+end_src
  - Generate html documentation:
    #+begin_src bash
      make USE_DOCKER=true html
    #+end_src

* Tests
  :PROPERTIES:
  :CUSTOM_ID: tests
  :END:
  [[https://cask.readthedocs.io/][Cask]] is used for testing. The tests are written using the Emacs
  built in ERT framework and follows the conventions of [[https://github.com/rejeep/ert-runner.el][ert runner]]
  although ert_runner is no longer used. There are also compilation
  tests, style check, package verification etc.
*** Setup
    :PROPERTIES:
    :CUSTOM_ID: tests_setup
    :END:
    - [[https://cask.readthedocs.io/en/latest/guide/installation.html][Install cask]]
    - Install all developer dependencies:
      #+BEGIN_SRC bash
      make deps
      #+END_SRC
*** Running
    :PROPERTIES:
    :CUSTOM_ID: tests_running
    :END:
    - Run the whole test suite:
      #+BEGIN_SRC bash
      make test
      #+END_SRC
    - Run only the unit/integration tests:
      #+BEGIN_SRC bash
      make ert-test
      #+END_SRC
    - Manually test the package with Emacs:
      #+BEGIN_SRC bash
      cask emacs -Q -L . --eval="(progn (require 'rg) (enable-default-bindings))"
      #+END_SRC


* Documentation
  :PROPERTIES:
  :CUSTOM_ID: documentation
  :END:
  The documentation is written in org mode. The export target is
  [[https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html][restructured text]] suitable for the [[http://www.sphinx-doc.org/en/master/][Sphinx]] documentation
  generator. Sphinx is used to export the output from org mode to info
  and HTML documentation. The resulting .rst files are used for the online
  documentation on [[https://readthedocs.io]].

  The end user documentation is generated after committing to the
  main repository. It's advisable to build
  both html and info documentation locally and verify the output to
  make sure the changes looks as expected.
*** Setup
    :PROPERTIES:
    :CUSTOM_ID: documentation_setup
    :END:
    - [[http://www.sphinx-doc.org/en/master/usage/installation.html][Install Sphinx]]
      #+BEGIN_SRC bash
      sudo apt install python3-sphinx python3-sphinx-rtd-theme
      #+END_SRC
    - Install makeinfo
      #+begin_src bash
      sudo apt install texinfo
      #+end_src
*** Building
    :PROPERTIES:
    :CUSTOM_ID: documentation_building
    :END:
    - HTML documentation
      #+BEGIN_SRC bash
      make html
      #+END_SRC
      Open =docs/rst/_build/html/index.html= in a browser.
    - Info documentation
      #+BEGIN_SRC bash
      make info
      #+END_SRC
      To view in emacs:
      #+BEGIN_SRC elisp
      C-u M-x info [RET]
      #+END_SRC
      Then select the =docs/rst/_build/info/rgel.info= file.


================================================
FILE: docs/gpl.org
================================================
#+TITLE: GNU General Public License
#+AUTHOR: David Landell
#+EMAIL: david.landell@sunnyhill.email
#+DATE: 2019
#+LANGUAGE: en
#+OPTIONS: broken-links:auto, toc:nil, email:nil, num:nil, ^:nil, author:nil, date:nil


#+BEGIN_EXPORT rst
.. _gpl:
#+END_EXPORT

#+INCLUDE: "../LICENSE" example


================================================
FILE: docs/index.org
================================================
#+TITLE: Rg Manual
#+AUTHOR: David Landell
#+EMAIL: david.landell@sunnyhill.email
#+DATE: 2019
#+LANGUAGE: en
#+OPTIONS: broken-links:auto, toc:nil, email:nil, num:nil, ^:nil, author:nil, date:nil

/rg.el/ is an Emacs search package based on the [[https://github.com/BurntSushi/ripgrep][ripgrep]] command line
tool. It allows you to interactively create searches, doing automatic
searches based on the editing context, refining and modifying search
results and much more. It is also highly configurable to be able to
fit different users' needs.

Throughout this manual this emacs package will be referred to as /rg/
while the command line utility will be referred to as /ripgrep/.

If you are used to built-in Emacs =rgrep= command, transitioning to
/rg/ should be simple. /rg/ provides a lot of extra features
but the basics are similar.

The big benefit of using /ripgrep/ instead of /grep/ as a backend is
speed. Especially when searching large source code repositories
where /ripgrep/ really shines. Please read [[http://blog.burntsushi.net/ripgrep/][this blog post]] for some
speed comparisons with other tools.

#+BEGIN_EXPORT rst
.. toctree::
   :maxdepth: 2

   usage
   configuration
   contribute
#+END_EXPORT

* License
  :PROPERTIES:
  :CUSTOM_ID: license
  :END:
  /rg/ 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 3
  of the License, or (at your option) any later version.

  /rg/ 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
  [[file:gpl.org::#gpl][GNU General Public License]] for more details.

#+BEGIN_EXPORT rst
.. toctree::
   :maxdepth: 2

   gpl
#+END_EXPORT


================================================
FILE: docs/org-bootstrap.el
================================================
;;; org-bootstrap.el --- Description -*- lexical-binding: t; -*-

;; Copyright (C) 2019 David Landell <david.landell@sunnyhill.email>
;;
;; Author: David Landell <david.landell@sunnyhill.email>
;; URL: https://github.com/dajva/rg.el

;; This file is not part of GNU Emacs.

;; 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 3
;; 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., 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301, USA.

;;; Commentary:

;;; Code:

(require 'ox-rst)
(require 'package)
(require 'rg)

;; General org mode settings

(setq org-odd-levels-only t)
(setq org-confirm-babel-evaluate nil)

;; org ox-rst settings
(setq org-rst-pygments-langs
      '((lisp "common-lisp")
        (cc "c++")
        (cperl "perl")
        (latex "tex")
        (shell-script "bash")
        (caml "ocaml")
        (sqlite3 "sqlite")))

(setq org-rst-code-block 'code-block)
(setq org-rst-link-use-ref-role t)
(setq org-rst-file-link-use-ref-role t)

(defun rg-format-todo (todo todo-type priority title tags contents)
  (when (eq todo-type 'todo)
    (let* ((padding "   ")
           (formated-contents
            (when contents
              (concat padding
                      (mapconcat 'identity (split-string contents "\n")
                                 (concat "\n" padding))))))
      (concat (format (concat ".. todo:: %s\n\n") title)
              formated-contents "\n"))))
(setq org-rst-format-inlinetask-function #'rg-format-todo)

(defun rg-format-drawer (name contents info)
  (let* ((lines (split-string contents "\n"))
         (heading (car lines))
         (body (cdr lines)))
    (format ".. %s:: %s\n%s\n\n"
            (downcase name)
            heading
            (concat "   " (mapconcat #'identity body (concat "\n" "   "))))))
(setq org-rst-format-drawer-function #'rg-format-drawer)

(defun rg-func-role-link (path desc backend)
  (rg-ref-role-link "func" path desc backend))

(defun rg-cmd-role-link (path desc backend)
  (rg-ref-role-link "cmd" path desc backend))

(defun rg-opt-role-link (path desc backend)
  (rg-ref-role-link "opt" path desc backend))

(defun rg-var-role-link (path desc backend)
  (rg-ref-role-link "var" path desc backend))

(defun rg-ref-role-link (role path desc backend)
  (when (eq backend 'rst)
    (if desc
        (format ":%s:`%s <%s>`" role desc path)
      (format ":%s:`%s`" role path))))

(push '("func" :export rg-func-role-link ) org-link-parameters)
(push '("cmd" :export rg-cmd-role-link ) org-link-parameters)
(push '("opt" :export rg-opt-role-link ) org-link-parameters)
(push '("var" :export rg-var-role-link ) org-link-parameters)

(add-to-list 'load-path nil)

(defvar rst-out-dir (getenv "RST_OUT_DIR"))

(defun rg-export-to-rst ()
  (interactive)
  (let ((outfile (org-export-output-file-name ".rst" nil rst-out-dir)))
    (org-export-to-file 'rst outfile)))

(provide 'org-bootstrap)

;;; org-bootstrap.el ends here


================================================
FILE: docs/rst/Makefile
================================================
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS    =
SPHINXBUILD   = sphinx-build
SOURCEDIR     = .
BUILDDIR      = _build

# Put it first so that "make" without argument is like "make help".
help:
	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

================================================
FILE: docs/rst/conf.py
================================================
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config

# -- Path setup --------------------------------------------------------------

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('.'))

# -- Project information -----------------------------------------------------

project = u'rg.el'
copyright = u'2019, David Landell'
author = u'David Landell'

# The short X.Y version
version = u''
# The full version, including alpha/beta/rc tags
release = u'2.4.0'

# -- General configuration ---------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
    'sphinx.ext.todo',
    'elispdomain'
]


# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
source_suffix = ['.rst']

# The master toctree document.
master_doc = 'index'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'en'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store', 'README.rst']

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = None


# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
#
# html_theme = 'alabaster'
html_theme = 'sphinx_rtd_theme'

# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".

# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself.  Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}


# -- Options for HTMLHelp output ---------------------------------------------

# Output file base name for HTML help builder.
htmlhelp_basename = 'rgeldoc'


# -- Options for LaTeX output ------------------------------------------------

latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    #
    # 'papersize': 'letterpaper',

    # The font size ('10pt', '11pt' or '12pt').
    #
    # 'pointsize': '10pt',

    # Additional stuff for the LaTeX preamble.
    #
    # 'preamble': '',

    # Latex figure (float) alignment
    #
    # 'figure_align': 'htbp',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
#  author, documentclass [howto, manual, or own class]).
latex_documents = [
    (master_doc, 'rgel.tex', u'rg.el Documentation',
     u'David Landell', 'manual'),
]


# -- Options for manual page output ------------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    (master_doc, 'rgel', u'rg.el Documentation',
     [author], 1)
]


# -- Options for Texinfo output ----------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    (master_doc, 'rgel', u'RG User Manual',
     author, 'RG', 'Search like a King with ripgrep in Emacs.',
     'Emacs'),
]

texinfo_elements = {'preamble': """
@definfoenclose strong,*,*
@definfoenclose emph,_,_
"""}

texinfo_show_urls='inline'
texinfo_no_detailmenu=True

# -- Options for Epub output -------------------------------------------------

# Bibliographic Dublin Core info.
epub_title = project

# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''

# A unique identification for the text.
#
# epub_uid = ''

# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']


# -- Extension configuration -------------------------------------------------

# -- Options for todo extension ----------------------------------------------

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True

add_function_parentheses=False


================================================
FILE: docs/rst/elispdomain.py
================================================
# -*- coding: utf-8 -*-
"""
Emacs Lisp Domain for Sphinx

Copyright 2014 by Jorgen Schäfer

"""

from sphinx import addnodes
from sphinx.domains import Domain, ObjType
from sphinx.locale import _
from sphinx.directives import ObjectDescription
from sphinx.roles import XRefRole
from sphinx.util.nodes import make_refnode


class ELispMarkup(ObjectDescription):
    def add_target_and_index(self, name, sig, signode):
        targetname = self.objtype + '-' + name
        if targetname not in self.state.document.ids:
            signode['names'].append(targetname)
            signode['ids'].append(targetname)
            signode['first'] = (not self.names)
            self.state.document.note_explicit_target(signode)

            objects = self.env.domaindata['el']['objects']
            key = (self.objtype, name)
            if key in objects:
                self.state_machine.reporter.warning(
                    'duplicate description of %s %s, ' % (self.objtype, name) +
                    'other instance in ' + self.env.doc2path(objects[key]),
                    line=self.lineno)
            objects[key] = self.env.docname
        indextext = self.get_index_text(self.objtype, name)
        if indextext:
            self.indexnode['entries'].append(('single', indextext,
                                              targetname, '', None))


class ELispFunction(ELispMarkup):
    def get_index_text(self, objectname, name):
        return "{} (function)".format(name)

    def handle_signature(self, sig, signode):
        if sig.startswith("("):
            sig = sig[1:]
        if sig.endswith(")"):
            sig = sig[:-1]
        name, args = sig.split(" ", 1)

        params = addnodes.desc_parameterlist()
        if args:
            params += addnodes.desc_name(name, name + " ")
        else:
            params += addnodes.desc_name(name, name)
        for arg in args.split():
            params += addnodes.desc_parameter(arg, arg)
        signode += params
        return name


class ELispVariable(ELispMarkup):
    def get_index_text(self, objectname, name):
        return "{} (variable)".format(name)

    def handle_signature(self, sig, signode):
        signode += addnodes.desc_name(sig, sig)
        return sig


class ELispCommand(ELispMarkup):
    option_spec = {
        'kbd': lambda x: x
    }

    def get_index_text(self, objectname, name):
        return "{} (command)".format(name)

    def handle_signature(self, sig, signode):
        kbd = self.options.get("kbd")
        name = sig
        if kbd:
            description = "{} ({})".format(kbd, name)
        else:
            description = "M-x {}".format(sig)

        signode += addnodes.desc_name(description, description)
        return name


class ELispOption(ELispMarkup):
    option_spec = {
        'default': lambda x: x
    }

    def get_index_text(self, objectname, name):
        return "{} (customize option)".format(name)

    def handle_signature(self, sig, signode):
        default = self.options.get("default")
        if default:
            description = "{} [{}]".format(sig, default)
        else:
            description = sig
        signode += addnodes.desc_name(description, description)
        return sig


class ELispDomain(Domain):
    """Emacs Lisp language domain."""
    name = 'el'
    label = 'ELisp'

    object_types = {
        'function': ObjType(_('function'), 'func'),
        'variable': ObjType(_('variable'), 'var'),
        'command': ObjType(_('command'), 'cmd'),
        'option': ObjType(_('variable'), 'opt'),
    }
    directives = {
        'function': ELispFunction,
        'variable': ELispVariable,
        'command': ELispCommand,
        'option': ELispOption,
    }
    roles = {
        'func': XRefRole(),
        'var': XRefRole(),
        'cmd': XRefRole(),
        'opt': XRefRole(),
    }
    initial_data = {
        'objects': {},  # fullname, type -> docname
    }

    def clear_doc(self, docname):
        for (fullname, type_), docname in self.data['objects'].items():
                if fullname == docname:
                    del self.data['objects'][fullname]

    def resolve_xref(self, env, fromdocname, builder, type_, target, node,
                     contnode):
        objects = self.data['objects']
        objtypes = self.objtypes_for_role(type_)
        for objtype in objtypes:
            if (objtype, target) in objects:
                return make_refnode(builder, fromdocname,
                                    objects[objtype, target],
                                    objtype + "-" + target,
                                    contnode, target + " " + objtype)

    def get_objects(self):
        for (name, type_), docname in self.data['objects'].items():
            yield name, name, type_, docname, type_ + '-' + name, 1


def setup(app):
    app.add_domain(ELispDomain)


================================================
FILE: docs/usage.org
================================================
#+TITLE: Usage
#+AUTHOR: David Landell
#+EMAIL: david.landell@sunnyhill.email
#+DATE: 2019
#+LANGUAGE: en
#+OPTIONS: broken-links:auto, toc:nil, email:nil, num:nil, ^:nil, author:nil, date:nil

#+INCLUDE: "utils.org"

* Installation
  :PROPERTIES:
  :CUSTOM_ID: installation
  :END:
  This version of /rg/ is supported on GNU Emacs
  {{{elisp((rg-emacs-min-version))}}} or later on Linux systems. It
  might work on older Emacsen and on other systems but such
  configurations are not tested. Patches for other OS:es are welcome.

  :RUBRIC:
  MELPA
  :END:
  Packages are published on [[https://stable.melpa.org/#/rg][MELPA Stable]] and [[http://melpa.org/#/rg][MELPA]]. From within Emacs,
  run =M-x package-install [RET] rg [RET]= to install from those
  sources.

  Enable default key bindings:
  #+BEGIN_SRC elisp
      (rg-enable-default-bindings)
  #+END_SRC
  The above will enable the default key map
  {{{elisp_code((rg-default-keymap))}}} under the default prefix key
  {{{elisp_code((edmacro-format-keys rg-keymap-prefix))}}}.

  :RUBRIC:
  Manual
  :END:
  Releases can alternatively be downloaded from [[https://github.com/dajva/rg.el/releases/latest][GitHub]] and installed
  manually. Put all elisp files in main directory in your load path
  and =require= the package in your init file.

  #+BEGIN_SRC elisp
      (require 'rg)
      (rg-enable-default-bindings)
  #+END_SRC

  You would also need to make sure all package requirements are
  met. For this version these are:
  #+BEGIN_SRC elisp :results value raw :exports results
      (mapconcat
       (lambda (dep)
         (format "- *%s* _%s_" (car dep) (cdr dep)))
       rg-package-deps
       "\n")
  #+END_SRC

  /rg/ is using autoloaded symbols which means it's also possible
  to defer loading if you have autoloading setup. That usually comes
  out of the box with =package-install=.

  :RUBRIC:
  Lazy loading
  :END:
  For lazy loading you don't want to call directly into the package
  during startup. Use a setup similar to this instead:

  #+BEGIN_SRC elisp
    (global-set-key (kbd "C-c s") #'rg-menu)
    (with-eval-after-load 'rg
       ;; Your settings goes here.
    )
  #+END_SRC

  If you don't want to use the transient menu interface, the following
  is needed to achieve lazy loading:
  #+BEGIN_SRC elisp
    ;; Workaround for emacs' lack of autoloaded keymaps.
    ;; This is essentially what use-package do.
    (defun rg-autoload-keymap ()
      (interactive)
      (if (not (require 'rg nil t))
          (user-error (format "Cannot load rg"))
        (let ((key-vec (this-command-keys-vector)))
          (global-set-key key-vec rg-global-map)
          (setq unread-command-events
                (mapcar (lambda (ev) (cons t ev))
                        (listify-key-sequence key-vec))))))

    (global-set-key (kbd "C-c s") #'rg-autoload-keymap)
    (with-eval-after-load 'rg
       ;; Your settings goes here.
    )
  #+END_SRC

  :RUBRIC:
  wgrep
  :END:
  This package use [[https://github.com/mhayashi1120/Emacs-wgrep][wgrep]] for editing capabilities in the rg results
  buffer. No setup is needed.

  :RUBRIC:
  Isearch integration
  :END:
  Optional [[#isearch_search][isearch integration]] can be enabled to allow you to extend
  isearch to trigger ripgrep searching.
  Enable it in your configuration with:
  #+BEGIN_SRC elisp
    (require 'rg-isearch)
    (define-key isearch-mode-map "\M-sr" 'rg-isearch-menu)
  #+END_SRC
  For the evil use case where isearch-mode is exited after first search hit,
  users would also want to add the binding to the =global-map= or
  similar.

  :RUBRIC:
  Interaction with the /ripgrep/ configuration file
  :END:
  The /ripgrep/ binary allows using a [[https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md#configuration-file][configuration file]] to set
  default values for command line flags. This package requires
  specific command line flags to function correctly and using a
  /ripgrep/ configuration may conflict with these requirements. Therefore
  the configuration file is ignored by default. This can be changed
  by the [[opt:rg-ignore-ripgreprc][rg-ignore-ripgreprc]] setting.

  :NOTE:
  Using the /ripgrep/ configuration file may break functionality of this
  package if you are not careful.
  :END:

  :RUBRIC:
  Interaction with xterm-color
  :END:
  This package is not written to be used with custom output colors
  provided by external packages like /xterm-color/. It relies on the
  color escape sequences so stripping these will break in unexpected
  ways.
  If you are using such packages, the advice is to hook such
  functionality into =compilation-filter-hook= instead of advising
  =compilation-filter=.

* Searching
  :PROPERTIES:
  :CUSTOM_ID: searching
  :END:
  Searching is done by invoking one of the different frontend
  commands. This package is built around recursive search based on three
  parameters; a single /directory/, /file type/ filter, and a search
  /pattern/. These three parameters can interactively be selected or
  figured out automatically by the package, depending on which command
  that is used.

  The underlying /ripgrep/ binary has the file type filter concept
  built in. You have a high level of control over which files to
  search and which to ignore. This is partly what makes it so fast,
  ignoring uninteresting files.

  In addition to the base parameters there are a lot of options that
  control how a search is done. These are typically selected from the
  [[#the_menu][rg-menu]] interface.

*** Case sensitivity
    Considering case when searching is an important feature of any
    search tool. This package gives you a lot of control over how to
    handle case sensitive and case insensitive search. It can be
    forced to *on* or *off* and set to *smart case*. The latter is
    similar to the /ripgrep/ =--smart-case= flag but is not using the
    flag directly. One thing to note about this is that the case
    insensitive setting controls the behavior when starting a new
    search. In the results buffer the setting is fixed to *on* or
    *off* but can be toggled easily with a key binding. See
    [[opt:rg-ignore-case][rg-ignore-case]] customization for the details of the configuration.

*** Interactive search
    :PROPERTIES:
    :CUSTOM_ID: basic_search
    :END:
    Two commands implements fully interactive search, where all the
    base parameters are selected from the mini buffer.

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg 'rg-global-map)
    #+END_SRC
    This command prompts for /query/, /file type/ and /directory/ and
    tries to suggest reasonable default values.
    The /query/ string is interpreted as a regular expression. Default
    for /query/ is the thing at point and for /directory/ it is the current
    directory.
    If the type of the currently visited file is recognized, the
    corresponding [[#file_type_aliases][file type alias]] is suggested as the /file type/
    parameter.

    Invoking this command with the /universal argument/ will trigger
    confirmation and potential modification of the [[#full_command_line_search][full command line]]
    that will invoke the /ripgrep/ binary.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-literal 'rg-global-map)
    #+END_SRC
    This command works in the same way as [[cmd:rg][rg]] but interprets the /query/
    string literally and not as a regular expression.

    Invoking this command with the /universal argument/ will trigger
    confirmation and potential modification of the [[#full_command_line_search][full command line]]
    that will invoke the /ripgrep/ binary.
    :END:
*** Project search
    :PROPERTIES:
    :CUSTOM_ID: project_search
    :END:
    A common scenario is to search through a whole project while
    visiting a file in the project. This essentially means identifying
    the project root and use that as the top /directory/ when invoking
    the /ripgrep/ binary. /rg/ supports several ways of identifying a
    project. Emacs' major project packages are supported including
    [[https://www.projectile.mx/en/latest/][projectile]], [[https://github.com/technomancy/find-file-in-project][find-file-in-project]] and builtin [[https://github.com/emacs-mirror/emacs/blob/master/lisp/progmodes/project.el][project.el]]. If
    none of these are used, the fallback is Emacs' =vc-backend=.

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-project 'rg-global-map)
    #+END_SRC
    Search in the current project. The /directory/ is selected via one
    of Emacs' project packages while /query string/ and /file type/
    are prompted for. The /query string/ is interpreted as a regular
    expression.
    :END:
*** Do what I mean
    :PROPERTIES:
    :CUSTOM_ID: do_what_i_mean
    :END:
    The *DWIM* family of search commands tries to be smart by figure
    out the search parameters from the context without
    prompting. Thanks to /ripgrep's/ speed, this allows for new ways of
    searching by invoking a dwim command and then /refine/ the
    search from the results buffer.

    These commands use the word (with the definition of word depending
    on context) under cursor as the /query/ string. The /file type/
    parameter is taken from the type of the currently visited file. If
    the current file type can not be identified all file types known
    to /ripgrep/ are used. The fallback can be customized with
    [[opt:rg-default-alias-fallback]]. The /directory/ parameter varies
    between these commands.

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-dwim-project-dir 'rg-global-map)
    #+END_SRC
    Do a *DWIM* search in the current [[#project_search][project]].
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-dwim-current-dir 'rg-global-map)
    #+END_SRC
    Do a *DWIM* search in the current directory.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-dwim-current-file 'rg-global-map)
    #+END_SRC
    Do a *DWIM* search in the current file. The /current file/ in this
    context is actually a file /pattern/ exactly matching the current
    file name in a search starting from current directory. Most of the
    time this means a single file but if there are multiple files with
    the same name in a sub directory, those will be searched as well.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-dwim 'rg-global-map)
    #+END_SRC
    This command combines all the *DWIM* commands to one. The default
    search is in the [[cmd:rg-dwim-project-dir][project dir]]. With one /universal argument/ [[cmd:rg-dwim-current-dir][current
    directory]] is used and with double /universal arguments/ a [[cmd:rg-dwim-current-file][file
    search]] is done.
    :END:
*** Isearch search
    :PROPERTIES:
    :CUSTOM_ID: isearch_search
    :END:
    Isearch integration is optional and need to be enabled explicitly
    in your emacs configuration. See [[#installation][installation]] for more info.

    This functionality is similar to emacs built in occur package but offers
    some additional choices for the search and provides the full
    functionality of the rg search result buffer.
    When enabled, the choosen binding can be used from isearch to
    trigger a menu for extending the isearch to do a ripgrep search in
    current file, current directory or current project.

*** File type aliases
    :PROPERTIES:
    :CUSTOM_ID: file_type_aliases
    :END:
    File type aliases are used in /ripgrep/ to filter out the files
    to search in. The /ripgrep/ binary comes with a default set
    of aliases that can be extended or overridden from this package by
    customizing [[opt:rg-custom-type-aliases]].

    An alias is a mapping between a name and a list of [[https://en.wikipedia.org/wiki/Glob_%2528programming%2529][glob patterns]]
    matching the files of interest. Selecting an alias when searching
    is done with completing read of the defined aliases. It is also
    possible to enter a custom glob pattern if there is no suitable
    alias defined for the file type.

    /rg/ defines some internal aliases:

    | Name         | Meaning                                                           |
    |--------------+-------------------------------------------------------------------|
    | *all*        | all defined types including [[opt:rg-custom-type-aliases][rg-custom-type-aliases]]                |
    | *everything* | all files. No filtering on type is done.                          |
    | *custom*     | used internally in this package for mapping custom glob patterns. |
    |--------------+-------------------------------------------------------------------|

    :WARNING:
    Do not use any of the internal aliases in [[opt:rg-custom-type-aliases][rg-custom-type-aliases]].
    That would interfere with the package internal usage.
    :END:

*** The menu
    :PROPERTIES:
    :CUSTOM_ID: the_menu
    :END:
    The global [[opt:rg-keymap-prefix][prefix key]] may be bound to a transient
    prefix command, which means that the key binding will popup a
    menu. This package is using the same popup menu backend called
    [[https://magit.vc/manual/transient][transient]] as the [[https://magit.vc/manual/magit][magit]] package. If you are familiar with magit
    this should feels like home.

    The menu is mostly interesting when you want to give specific
    command line flags to the /ripgrep/ binary. When you just want to do
    a quick search based on the defaults the menu basically acts as a
    normal keymap.

    Pressing the =rg-menu= [[opt:rg-keymap-prefix][prefix key]] will popup the menu where command
    line flags can be selected before triggering the wanted search
    function. The menu can be customized via the transient API as
    usual. This package contains some shortcuts to directly add a new
    command to the menu when defining the command via the
    [[func:rg-define-search]] macro.

    #+BEGIN_SRC elisp
      (rg-define-search rg-word
        :format literal
        :flags ("--word-regexp")
        :menu ("Custom" "w" "Word"))
    #+END_SRC

    The =:menu= keyword in the above invocation will trigger insertion
    of a new menu item bound to key =w= with description *Word*. The
    new menu item will be put under the *Custom* group. This group is
    not available in the original menu so it will be created.

    The menu can be triggered from the [[#results_buffer][results buffer]] with the =m= key.
    The commands in the menu differs, depending on from where it's
    triggered but the available options are the same. The menu does
    not show all options by default.

    The visible options can be controlled by the transient suffix
    levels documented [[https://magit.vc/manual/transient/Enabling-and-Disabling-Suffixes.html#Enabling-and-Disabling-Suffixes][here]].  To modify what is enabled at the default
    level 4 press =C-x l= to enter edit mode when the menu is
    visible. Then select the option by pressing the key sequence that
    activates the option and choose the level 4 for that option. It's
    also possible to use the transient edit mode for modifying the
    overall level of the menu to enable more options at once.

* Results buffer
  :PROPERTIES:
  :CUSTOM_ID: results_buffer
  :END:
  The results of a search is shown in the results buffer. This buffer
  displays search parameters, the full command line and the output of
  the /ripgrep/ binary. It supports basic navigation between search
  results editing of the file contents directly from the search
  buffer and also modification of the current search. The results
  buffer is a modified /compilation/ buffer and some key bindings and
  functionality is inherited from the parent and from /grep mode/.

*** Navigation
    Navigation works mostly as in grep/compilation buffers.

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'compilation-next-error 'rg-mode-map (kbd "M-n"))
    #+END_SRC
    Move to next line with a match.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'compilation-previous-error 'rg-mode-map (kbd "M-p"))
    #+END_SRC
    Move to previous line with a match.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'next-error-no-select 'rg-mode-map)
    #+END_SRC
    Move to next line with a match, show that file in other buffer and highlight the
    match.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'previous-error-no-select 'rg-mode-map)
    #+END_SRC
    Move to previous line with a match, show that file in other buffer and highlight the
    match.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-next-file 'rg-mode-map)
    #+END_SRC
    Move to next file header if the results is grouped under a file
    header (See [[opt:rg-group-result]]).
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-prev-file 'rg-mode-map)
    #+END_SRC
    Move to previous file header if the results is grouped under a file
    header (See [[opt:rg-group-result]]).
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'compilation-next-file 'rg-mode-map)
    #+END_SRC
    Move first match in previous file.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'compilation-previous-file 'rg-mode-map)
    #+END_SRC
    Move last match in previous file.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'compile-goto-error 'rg-mode-map)
    #+END_SRC
    Visit match in file.
    :END:

    If [[opt:rg-group-result][rg-group-result]] is enabled, the [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Imenu.html][Imenu]] facility is configured to
    jump across files.

*** Refine search
    From the results buffer it's easy to change the search
    parameters. Some bindings toggle a flag while others allow you to
    interactively change the [[#searching][base
    parameters]].

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-rerun-change-dir 'rg-mode-map)
    #+END_SRC
    Interactively change search /directory/.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-rerun-change-files 'rg-mode-map)
    #+END_SRC
    Interactively change searched /file types/.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-rerun-change-literal 'rg-mode-map)
    #+END_SRC
    Interactively change /search string/ interpret the string literally.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-rerun-change-regexp 'rg-mode-map)
    #+END_SRC
    Interactively change /search string/ interpret the string as a regular
    expression.
    :END:

    :TIP:
    [[cmd:rg-rerun-change-regexp]] and [[cmd:rg-rerun-change-literal]] are
    used for switching between regular expression and literal
    search. So for quick switching between search modes with the same
    search string,  just press the respective key and then =RET=.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-recompile 'rg-mode-map)
    #+END_SRC
    Rerun the current search without changing any parameters.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-rerun-toggle-case 'rg-mode-map)
    #+END_SRC
    Toggle case sensitivity of search. The state of the flag is shown
    in the *[case]* header field.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-rerun-toggle-ignore 'rg-mode-map)
    #+END_SRC
    Toggle if ignore files are respected. The state of the flag is shown
    in the *[ign]* header field.
    :END:

    :TIP:
    It is possible to create and bind your own toggle flags with the
    macro [[func:rg-define-toggle]].
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-menu 'rg-mode-map)
    #+END_SRC
    Fire up [[#the_menu][the menu]] for full access to options and flags.
    :END:


*** Full command line search
    :PROPERTIES:
    :CUSTOM_ID: full_command_line_search
    :END:
    Some search commands (See [[cmd:rg]] or [[cmd:rg-literal]]) allow you to
    edit the final command line before invoking the search by giving a
    /universal argument/. This can be used to invoke features of the
    /ripgrep/ binary that is not supported in this package's
    interface. This could be specific flags, searching in multiple
    directories etc.

    :NOTE:
    Using full command line search will disable refinement of the
    search from the result buffer.
    :END:

*** History navigation
    :PROPERTIES:
    :CUSTOM_ID: history_navigation
    :END:
    Each search result is stored in the search history, which is a per
    results buffer property. History can be navigated back and
    forward, the forward history is cleared when a new search is done.

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-back-history 'rg-mode-map)
    #+END_SRC
    Navigate back in history.
    :END:

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'rg-forward-history 'rg-mode-map)
    #+END_SRC
    Navigate forward in history.
    :END:

    :TIP:
    The key bindings here are slightly inconvenient so invoking this
    via [[#the_menu][the menu]] by pressing =m b= and =m w= is more ergonomic.
    :END:

*** Edit and apply (wgrep)
    :PROPERTIES:
    :CUSTOM_ID: edit_and_apply
    :END:
    The results buffer supports inline editing via the [[https://github.com/mhayashi1120/Emacs-wgrep][wgrep]]
    package. This is setup automatically when /rg/ is loaded.

    :COMMAND:
    #+BEGIN_SRC elisp :results value raw :exports results
    (rg-command-info #'wgrep-change-to-wgrep-mode 'rg-mode-map)
    #+END_SRC
    Make the search results editable by enabling =wgrep= mode.
    When done press =C-c C-c= to commit your changes to the underlying
    files or =C-c C-k= to drop the changes.
    :END:

* Search management
  :PROPERTIES:
  :CUSTOM_ID: search_management
  :END:
  The result buffer is named {{{elisp_code((format "\*%s\*"
  rg-buffer-name))}}} and /rg/ reuse the same result buffer for new
  searches. If you want to store a search while continuing doing new searches
  there are two ways of doing that.

  :COMMAND:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-command-info #'rg-save-search 'rg-mode-map)
  #+END_SRC
  Save the search buffer by renaming it to a unique new name.
  This is available both outside and inside a result buffer. Outside
  of the result buffer it's bound to
  {{{elisp_code((rg-key-for-command #'rg-save-search 'rg-global-map))}}}.

  If you want to keep all search buffers until manually killed you can
  use this snippet in your init file.
  #+BEGIN_SRC elisp
    (defadvice rg-run (before rg-run-before activate)
      (rg-save-search))
  #+END_SRC
  :END:

  :COMMAND:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-command-info #'rg-save-search-as-name 'rg-mode-map)
  #+END_SRC
  Save the search buffer and interactively give it a specific name.
  This is available both outside and inside a result buffer. Outside
  of the result buffer it's bound to
  {{{elisp_code((rg-key-for-command #'rg-save-search-as-name 'rg-global-map))}}}.
  :END:

  The default buffer name can be customized with [[opt:rg-buffer-name]]. This
  setting considers dir local variables and it's even possible to use
  a function to get a really dynamic setup.

  Having a lot of search buffers floating around can easily get
  messy. To help keeping this under control there is a search
  manager. The manager is simply a modified =ibuffer= that lists all
  the results buffers, shows some data about the searches and make it
  possible to kill of some unused etc.

  :COMMAND:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-command-info #'rg-list-searches 'rg-mode-map)
  #+END_SRC
  Open the search manager.
  This is available both in result buffer and globally bound to
  {{{elisp_code((rg-key-for-command #'rg-list-searches 'rg-global-map))}}}.
  :END:

  :COMMAND:
  #+BEGIN_SRC elisp :results value raw :exports results
  (rg-command-info #'rg-kill-saved-searches 'rg-global-map)
  #+END_SRC
  Kill all saved searches except for the one that matches [[opt:rg-buffer-name]].
  This is available both in result buffer and globally bound to
  {{{elisp_code((rg-key-for-command #'rg-kill-saved-searches 'rg-global-map))}}}.
  :END:

  :WARNING:
  If you have a dynamic [[opt:rg-buffer-name]] setup, only one buffer that
  matches your current criteria (dir locals or project for instance)
  will be kept. So be careful when killing saved searches to avoid
  losing important search results.
  :END:

* Multi line search
  :PROPERTIES:
  :CUSTOM_ID: multi_line_search
  :END:
  By default, ripgrep does matching per line. The =--multiline= flag
  can be used for enabling matching over multiple lines. This
  flag is available in the [[#the_menu][rg-menu]] as an option. The =--multiline=
  flag does not match new line characters with the =.= as one might
  expect though. A separate flag is used to allow this,
  =--multiline-dotall=. The casual user of multi line search commonly
  want this flag on by default so it's recommended to add this to
  [[opt:rg-command-line-flags]] to avoid having to trigger this flag
  manually from the menu.

  See the ripgrep manual page for more info about the multi line
  flags.


================================================
FILE: docs/utils.org
================================================
#+MACRO: elisp src_elisp[:results value raw :exports results]{$1}
#+MACRO: elisp_code src_elisp[:results value :exports results]{$1}

#+NAME: utils
#+BEGIN_SRC elisp :results output drawer :exports none
  (require 'cl-lib)
  (require 'cus-edit)
  (require 'edmacro)
  (require 'help)
  (require 'package)
  (require 'rg)

  (defvar rg-package-version nil)
  (defvar rg-package-deps nil)
  (rg-enable-menu)

  (defun rg-package-info ()
    (let ((file-name "../rg.el"))
      (with-temp-buffer
        (insert-file-contents file-name)
        (condition-case nil
            (package-buffer-info)
          (error "Invalid package")))))

  (defun rg-extract-package-info ()
    (let ((desc (rg-package-info)))
      (setf rg-package-version (package-version-join (package-desc-version desc)))
      (dolist (req (package-desc-reqs desc))
        (push (cons (car req) (package-version-join (cadr req))) rg-package-deps))))

  (defun rg-package-deps ()
    (when (not rg-package-deps)
      (rg-extract-package-info))
    rg-package-deps)

  (defun rg-package-version ()
    (when (not rg-package-version)
      (rg-extract-package-info))
    rg-package-version)

  (defun rg-emacs-min-version ()
    (cdr (assq 'emacs (rg-package-deps))))

  (defun rg-default-keymap ()
    (if rg-use-transient-menu
        "rg-menu"
      "rg-global-map"))

  (defun rg-custom-info (sym &optional default)
    (let* ((type (custom-variable-type sym))
           (value (or default
                      (if (and (consp type) (eq (car type) 'key-sequence))
                          (edmacro-format-keys (symbol-value sym))
                        (symbol-value sym)))))
      (format "%s\n:default: %S" sym value)))

  (defun rg-face-info (face)
    (cl-assert (facep face))
    (format "%s\n:default: %s" face (face-attribute face :inherit)))

  (defun rg-key-for-command (sym map &optional wanted-key)
    (cl-assert (commandp sym))
    (when-let ((keys (where-is-internal sym (symbol-value map))))
      (let* ((key (edmacro-format-keys (or
                                        (and wanted-key
                                             (cl-find wanted-key keys :test 'equal))
                                        (car keys))))
             (prefix (when (and key
                                (eq map 'rg-global-map))
                       (edmacro-format-keys rg-keymap-prefix))))
        (if prefix
            (format "%s %s" prefix key)
          (format "%s" key)))))

  (defun rg-command-info (sym map &optional wanted-key)
    (if-let ((key-sequence (rg-key-for-command sym map wanted-key)))
        (format "%s\n:kbd: %s" sym key-sequence)
      (format "%s\n" sym)))

  (defun rg-function-info (sym)
    (cl-assert (fboundp sym))
    (let ((args (mapconcat #'symbol-name (help-function-arglist sym) " ")))
      (format "(%s %s)\n" sym args)))
#+END_SRC

call_utils()

#+BEGIN_EXPORT rst
.. default-domain:: el
#+END_EXPORT


================================================
FILE: rg-header.el
================================================
;;; rg-header.el --- Header line for rg-mode -*- lexical-binding: t; -*-

;; Copyright (C) 2018 David Landell <david.landell@sunnyhill.email>
;;
;; Author: David Landell <david.landell@sunnyhill.email>
;; URL: https://github.com/dajva/rg.el

;; This file is not part of GNU Emacs.

;; 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 3
;; 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., 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301, USA.

;;; Commentary:

;; Header line format for rg-mode result buffer.

;;; Code:

(require 'mouse)

(declare-function rg-cur-search-pattern "rg-result.el")


;; Customization
(defcustom rg-header-max-search-string-length nil
  "The max line length of header line search string item."
  :type '(choice (const :tag "Don't truncate" nil)
                 (number :tag "The max width"))
  :group 'rg)


;; Faces
(defface rg-toggle-on-face
  '((t :inherit rg-file-tag-face))
  "face for toggle \"on\" text in header."
  :group 'rg-face)

(defface rg-toggle-off-face
  '((t :inherit rg-error-face))
  "face for toggle \"off\" text in header."
  :group 'rg-face)

(defface rg-literal-face
  '((t :inherit rg-filename-face))
  "face for literal label in header."
  :group 'rg-face)

(defface rg-regexp-face
  '((t :inherit compilation-line-number))
  "face for regexp label in header."
  :group 'rg-face)


;; Defuns
(defun rg-header-render-label (labelform)
  "Return a fontified header label.
LABELFORM is either a string to render or a form where the `car' is a
conditional and the two following items are then and else specs.
Specs are lists where the the `car' is the labels string and the
`cadr' is font to use for that string."
  (list '(:propertize "[" font-lock-face (header-line bold))
        (cond
         ((stringp labelform)
          `(:propertize ,labelform font-lock-face (header-line bold)))
         ((listp labelform)
          (let* ((condition (nth 0 labelform))
                 (then (nth 1 labelform))
                 (else (nth 2 labelform)))
            `(:eval (if ,condition
                        (propertize ,(nth 0 then) 'font-lock-face '(,(nth 1 then) header-line bold))
                      (propertize ,(nth 0 else) 'font-lock-face '(,(nth 1 else) header-line bold))))))
         (t (error "Not a string or list")))
        '(:propertize "]" font-lock-face (header-line bold))
        '(": ")))

(defun rg-header-render-toggle (on)
  "Return a fontified toggle symbol.
If ON is non nil, render \"on\" string, otherwise render \"off\"
string."
  `(:eval (let* ((on ,on)
                 (value (if on "on " "off"))
                 (face (if on 'rg-toggle-on-face 'rg-toggle-off-face)))
            (propertize value 'font-lock-face `(bold ,face)))))

(defun rg-header-mouse-action (command help &rest items)
  "Add a keymap with mouse click action for COMMAND.
When hoovering HELP is shown as a tooltip.  ITEMS is the header line
items that the map will be applied to."
  (let ((map (make-sparse-keymap)))
    (define-key map
      (if (or (> emacs-major-version 30)
              (and (= emacs-major-version 30) (>= emacs-minor-version 2)))
          [header-line mouse-1]
        [header-line mouse-2])
      (lambda (click)
        (interactive "e")
        (mouse-select-window click)
        (call-interactively command)))
    `(:propertize ,items mouse-face header-line-highlight
                  help-echo ,help
                  keymap ,map)))

(defun rg-header-truncate-search-pattern (search)
  "Truncate SEARCH if it exceeds `rg-header-max-search-string-length'."
  (if (rg-header-truncates-p search)
      (truncate-string-to-width search
                                rg-header-max-search-string-length
                                0
                                nil
                                t)
    search))

(defun rg-header-truncates-p (search)
  "Verify that SEARCH would be truncated."
  (and (numberp rg-header-max-search-string-length)
       (< rg-header-max-search-string-length (length search))))

(defun rg-header-search-help ()
  "Get the search help for the current buffer."
  (let ((pattern (rg-cur-search-pattern)))

    (if (rg-header-truncates-p pattern)
        (concat "Change search string: " pattern)
      "Change search string")))

;; Use full-command here to avoid dependency on rg-search
;; struct. Should be properly fixed.
(defun rg-create-header-line (search full-command)
  "Create the header line for SEARCH.
If FULL-COMMAND specifies if the full command line search was done."
  (let ((itemspace "  "))
    (setq header-line-format
          (if full-command
              (list (rg-header-render-label "command line") "no refinement")
            (list
             (rg-header-mouse-action
              'rg-rerun-toggle-rexexp-literal "Toggle literal/regexp"
              (rg-header-render-label `((rg-search-literal ,search)
                                        ("literal" rg-literal-face)
                                        ("regexp" rg-regexp-face))))
             (rg-header-mouse-action
              'rg-rerun-change-query (rg-header-search-help)
              `(:eval (rg-header-truncate-search-pattern (rg-search-pattern ,search))))
             itemspace
             (rg-header-render-label "files")
             (rg-header-mouse-action
              'rg-rerun-change-files "Change file types"
              `(:eval (rg-search-files ,search)))
             itemspace
             (rg-header-render-label "case")
             (rg-header-mouse-action
              'rg-rerun-toggle-case "Toggle case"
              (rg-header-render-toggle
               `(not (member "-i" (rg-search-flags ,search)))))
             itemspace
             (rg-header-render-label "ign")
             (rg-header-mouse-action
              'rg-rerun-toggle-ignore "Toggle ignore"
              (rg-header-render-toggle
               `(not (member "--no-ignore" (rg-search-flags ,search)))))
             itemspace
             (rg-header-render-label "hits")
               '(:eval (format "%d" rg-hit-count)))))))

(provide 'rg-header)

;;; rg-header.el ends here


================================================
FILE: rg-history.el
================================================
;;; rg-history.el --- History navigation in rg.el -*- lexical-binding: t; -*-

;; Copyright (C) 2018 David Landell <david.landell@sunnyhill.email>
;;
;; Author: David Landell <david.landell@sunnyhill.email>
;; URL: https://github.com/dajva/rg.el

;; This file is not part of GNU Emacs.

;; 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 3
;; 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., 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301, USA.

;;; Commentary:

;;; Code:

(require 'cl-lib)
(require 'subr-x)

(cl-defstruct (rg-history (:constructor rg-history-create)
                          (:copier nil))
  past                    ; list of searches for backward navigation
  present                 ; current search
  future)                 ; list of searches for forward navigation

(defun rg-history-push (item instance)
  "Push a new ITEM to the rg-history INSTANCE."
  (when-let (present (rg-history-present instance))
    (push present (rg-history-past instance)))
  (setf (rg-history-present instance) item)
  (setf (rg-history-future instance) nil))

(defun rg-history-back (instance)
  "Move back in the rg-history INSTANCE.
Return the new current search."
  (when-let (prev (pop (rg-history-past instance)))
    (push (rg-history-present instance) (rg-history-future instance))
    (setf (rg-history-present instance) prev)))

(defun rg-history-forward (instance)
  "Move forward in the rg-history INSTANCE.
Return the new current search."
  (when-let (next (pop (rg-history-future instance)))
    (push (rg-history-present instance) (rg-history-past instance))
    (setf (rg-history-present instance) next)))

(provide 'rg-history)

;;; rg-history.el ends here


================================================
FILE: rg-ibuffer.el
================================================
;;; rg-ibuffer.el --- List search buffers for rg-mode -*- lexical-binding: t; -*-

;; Copyright (C) 2018 David Landell <david.landell@sunnyhill.email>
;;
;; Author: David Landell <david.landell@sunnyhill.email>
;; URL: https://github.com/dajva/rg.el

;; This file is not part of GNU Emacs.

;; 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 3
;; 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., 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301, USA.

;;; Commentary:

;; Use ibuffer to list active searches.

;;; Code:

(require 'ibuf-ext)
(require 'ibuffer)
(require 'rg-result)

(defconst rg-search-list-buffer-name "*Searches rg*")

(defun rg-ibuffer-search-updated()
  "This function is executed when search list buffer is updated."
  (when-let ((list-buffer (get-buffer rg-search-list-buffer-name)))
    (ignore-errors
      (with-current-buffer list-buffer
        (ibuffer-update nil t)))))

(defun rg-ibuffer-buffer-killed ()
  "Function run when the search list buffer is killed."
  (remove-hook 'rg-filter-hook #'rg-ibuffer-search-updated))

(define-ibuffer-column rg-search-term
  (:name "Search" :props ('face 'rg-match-face))
  (ignore mark)
  (if rg-cur-search
      (rg-search-pattern rg-cur-search)
    "N/A"))

(define-ibuffer-column rg-hit-count
  (:name "Hits")
  (ignore mark)
  (number-to-string rg-hit-count))

(define-ibuffer-column rg-search-dir
  (:name "Directory" :props ('face 'rg-filename-face))
  (ignore mark)
  (if rg-cur-search
      (rg-search-dir rg-cur-search)
    "N/A"))

(define-ibuffer-column rg-file-types
  (:name "Type")
  (ignore mark)
  (if rg-cur-search
      (rg-search-files rg-cur-search)
    "N/A"))

;;;###autoload
(defun rg-list-searches ()
  "List all `rg-mode' buffers in `ibuffer'."
  (interactive)
  (let ((other-window (equal current-prefix-arg '(4))))
    (ibuffer other-window rg-search-list-buffer-name '((mode . rg-mode)) nil nil nil
             '((mark " "
                     (name 16 16 nil :elide) " "
                     (rg-search-term 18 18 nil :elide) " "
                     (rg-hit-count 7 7) " "
                     (rg-file-types 7 7) " "
                     (process 10 10)
                     (rg-search-dir 20 -1 nil :elide) " ")))
    (add-hook 'rg-filter-hook #'rg-ibuffer-search-updated)
    (with-current-buffer rg-search-list-buffer-name
      (ibuffer-auto-mode)
      (set (make-local-variable 'ibuffer-use-header-line) nil)
      (ibuffer-clear-filter-groups)
      (add-hook 'kill-buffer-hook #'rg-ibuffer-buffer-killed nil t))))

(provide 'rg-ibuffer)

;;; rg-ibuffer.el ends here


================================================
FILE: rg-info-hack.el
================================================
;;; rg-info-hack.el --- Make sure rg.el info documentation looks good -*- lexical-binding: t; -*-

;; Copyright (C) 2019 David Landell <david.landell@sunnyhill.email>
;;
;; Author: David Landell <david.landell@sunnyhill.email>
;; URL: https://github.com/dajva/rg.el

;; This file is not part of GNU Emacs.

;; 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 3
;; 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., 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301, USA.

;;; Commentary:

;;; Code:
(require 'info)

(define-advice info-insert-file-contents
    (:after (&rest _) sphinx-info-insert-file-contents)
  "Hack to hide \"See\" in references.
This makes `Info-hide-note-references' buffer-local and
automatically set to `hide' iff it can be determined that this file
is the rg.el documentation and was created from a Texinfo file
  generated by Sphinx."
  (set (make-local-variable
	'Info-hide-note-references)
       (default-value 'Info-hide-note-references))
  (save-excursion
    (save-restriction
      (widen) (goto-char (point-min))
      (when (and (search-forward "* RG:" nil t)
                 (search-forward
                  "Generated by Sphinx"
                  (save-excursion (search-forward "\x1f" nil t)) t))
        (set (make-local-variable 'Info-hide-note-references)
             'hide)))))

(provide 'rg-info-hack)

;;; rg-info-hack.el ends here


================================================
FILE: rg-isearch.el
================================================
;;; rg-isearch.el --- rg integration into isearch -*- lexical-binding: t; -*-

;; Copyright (C) 2020 David Landell <david.landell@sunnyhill.email>
;;
;; Author: David Landell <david.landell@sunnyhill.email>
;; URL: https://github.com/dajva/rg.el

;; This file is not part of GNU Emacs.

;; 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 3
;; 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., 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301, USA.

;;; Commentary:

;; This file provides rg isearch integration.
;; Add this to your configuration to bind chosen key in isearch minibuffer:
;;
;; (define-key isearch-mode-map "\M-sr" 'rg-isearch-menu)
;;

;; See info node `(rgel)Isearch search' for documentation or online at https://rgel.readthedocs.io/.

;;; Code:

(require 'rg)

(defun rg-get-isearch-string ()
  "Extract the isearch string from the last isearch."
  ;; Mimic what `isearch-occur' does.
  (or (cond
       ;; We can't handle arbitrary functions so just use the string.
       ((functionp isearch-regexp-function) isearch-string)
       ;; isearch-occur handles this as word search so insert word boundary
       (isearch-regexp-function (concat "\b" isearch-string "\b"))
       (isearch-regexp isearch-string)
       (t isearch-string))
      ""))

;;;###autoload (autoload 'rg-isearch-current-file "rg-isearch.el" "" t)
(rg-define-search rg-isearch-current-file
  "Run ripgrep on current file searching for latest isearch string."
  :dir current
  :query (rg-get-isearch-string)
  :format literal
  :files (rg-get-buffer-file-name)
  :dir current)

;;;###autoload (autoload 'rg-isearch-current-dir "rg-isearch.el" "" t)
(rg-define-search rg-isearch-current-dir
  "Run ripgrep in current directory searching for latest isearch string
in files matching the current file type."
  :query (rg-get-isearch-string)
  :format literal
  :files current
  :dir current)

;;;###autoload (autoload 'rg-isearch-project "rg-isearch.el" "" t)
(rg-define-search rg-isearch-project
  "Run ripgrep in current project searching for latest isearch string
in files matching the current file type."
  :dir project
  :query (rg-get-isearch-string)
  :format literal
  :files current)

;;;###autoload (autoload 'rg-isearch-menu "rg-isearch.el" "" t)
(transient-define-prefix rg-isearch-menu ()
  "Show menu for rg isearch commands."
  [:description "Search with ripgrep"
    (3 "f" "File" rg-isearch-current-file--transient)
    (3 "d" "Dir" rg-isearch-current-dir--transient)
    (3 "p" "Project" rg-isearch-project--transient)])

(provide 'rg-isearch)

;;; rg-isearch.el ends here


================================================
FILE: rg-menu.el
================================================
;;; rg-menu.el --- Menu interface for rg -*- lexical-binding: t; -*-

;; Copyright (C) 2017 David Landell <david.landell@sunnyhill.email>
;;
;; Author: David Landell <david.landell@sunnyhill.email>

;; This file is not part of GNU Emacs.

;; 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 3
;; 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., 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301, USA.

;;; Commentary:

;; Support a menu interface for rg.el based on transient.

;;; Code:

(require 'rg-result)
(require 'seq)
(require 'transient)
(require 'cl-lib)

;; Forward declarations
(declare-function rg "rg.el")
(declare-function rg-literal "rg.el")
(declare-function rg-dwim "rg.el")
(declare-function rg-project "rg.el")
(declare-function rg-dwim-current-dir "rg.el")
(declare-function rg-dwim-current-file "rg.el")
(declare-function rg-list-searches "rg.el")
(declare-function rg-save-search "rg.el")
(declare-function rg-save-search-as-name "rg.el")
(defvar rg-keymap-prefix)
(defvar rg-command-line-flags-function)

(defun rg-menu-search-initial-value ()
  "Provide initial value for `rg-menu' transient command."
  (when (eq major-mode 'rg-mode)
    (rg-search-flags rg-cur-search)))

(eval-and-compile
  (defun rg-menu-create-search-body (func)
    "Call FUNC from search menu with the flags set in the transient menu."
    `((let* ((transient-flags (transient-args transient-current-command))
             (function-flags (funcall rg-command-line-flags-function nil))
             (rg-command-line-flags-function
              (lambda (flags)
                (append function-flags transient-flags flags))))
        (call-interactively #',func))))

  (defun rg-menu-create-rerun-body (func)
    "Call FUNC from rerun menu with flags extracted with ARGFUNC.
If INTERACTIVE is non nil, call func interactively, otherwise call it
regularly."
    `((let ((transient-flags (transient-args transient-current-command))
            (current-flags (rg-search-flags rg-cur-search)))
        (setf (rg-search-flags rg-cur-search) (seq-uniq (append current-flags transient-flags))))
      (if (commandp #',func)
          (call-interactively #',func)
        (,func))))

  (defun rg-menu-assemble-transient-wrapper (func body)
    "Create a defun with name `FUNC--transient' with BODY."
    (let ((func-name (concat (symbol-name func) "--transient"))
          (doc-string (format "Transient wrapper around `%s' for `rg-menu'."
                              (symbol-name func))))
      `(progn
         (defun ,(intern func-name) ()
           (interactive)
           ,@body)
         (put ',(intern func-name) 'function-documentation
              ;; quote to defer evalutation until func is available
              '(concat ,doc-string "\n\n" (documentation ',func)))))))

(defmacro rg-menu-wrap-transient-search (func)
  "Wrap FUNC with a command that apply transient arguments to the search.
FUNC is an initial search function and not a rerun function."
  (rg-menu-assemble-transient-wrapper
   func
   (rg-menu-create-search-body func)))

(defmacro rg-menu-wrap-transient-rerun (func)
  "Wrap FUNC with a command that apply transient arguments to the rerun.
FUNC is an rerun function invoked from an `rg-mode' buffer."
  (rg-menu-assemble-transient-wrapper
   func
   (rg-menu-create-rerun-body func)))

;; Regular rg entries
(rg-menu-wrap-transient-search rg)
(rg-menu-wrap-transient-search rg-literal)
(rg-menu-wrap-transient-search rg-dwim)
(rg-menu-wrap-transient-search rg-project)
(rg-menu-wrap-transient-search rg-dwim-current-dir)
(rg-menu-wrap-transient-search rg-dwim-current-file)
(rg-menu-wrap-transient-search rg-list-searches)
(rg-menu-wrap-transient-search rg-save-search)
(rg-menu-wrap-transient-search rg-save-search-as-name)
(rg-menu-wrap-transient-search rg-back-history)
(rg-menu-wrap-transient-search rg-forward-history)

;; Rerun rg entries
(rg-menu-wrap-transient-rerun rg-rerun)
(rg-menu-wrap-transient-rerun rg-rerun-change-regexp)
(rg-menu-wrap-transient-rerun rg-rerun-change-literal)
(rg-menu-wrap-transient-rerun rg-rerun-change-files)
(rg-menu-wrap-transient-rerun rg-rerun-change-dir)

;;;###autoload (autoload 'rg-menu "rg-menu.el" "" t)
(transient-define-prefix rg-menu ()
  "Show menu buffer for rg commands."
  :man-page "rg"
  :value 'rg-menu-search-initial-value
  ["Switches"
   (3 "-h" "Search hidden files" "--hidden")
   (6 "-a" "Search binary files" "--text")
   (4 "-z" "Search zipped files" "--search-zip")
   (4 "-v" "Invert match" "--invert-match")
   (4 "-U" "Multi line" "--multiline")
   (4 "-." "Dot all" "--multiline-dotall")
   (3 "-w" "Search words" "--word-regexp")
   (5 "-x" "Search lines" "--line-regexp")
   (5 "-P" "Use PCRE2 regexps" "--pcre2")
   (4 "-1" "Don't cross file system" "--one-file-system")
   (6 "-L" "Follow symlinks" "--follow")
   (3 "-n" "Override ignore files" "--no-ignore")]
  ["Options"
   (3 "-C" "Show context" "--context=")
   (6 "-B" "Show context before" "--before-context=")
   (6 "-A" "Show context after" "--after-context=")
   (4 "-M" "Omit long lines" "--max-columns=")
   (4 "-m" "Max matches per file" "--max-count=")
   (6 "-s" "Ignore large files" "--max-filesize=")
   (4 "-g" "Filter files glob" "--glob=")
   (6 "-i" "Filter files glob (no case)" "--iglob=")
   (4 "-T" "Exclude files types" "--type-not=")
   (5 "-S" "Sort result" "--sort=")
   (5 "-R" "Reverse sort result" "--sortr=")
   (6 "-E" "Force encoding" "--encoding=")
   (6 "-r" "Replace match" "--replace=")]
  [[:if-not-mode rg-mode
    :description "Search"
    (3 "d" "Dwim project" rg-dwim--transient)
    (4 "c" "Dwim current directory" rg-dwim-current-dir--transient)
    (4 "f" "Dwim current file" rg-dwim-current-file--transient)
    (3 "r" "Regex" rg--transient)
    (3 "t" "Literal" rg-literal--transient)
    (3 "p" "Project" rg-project--transient)]
   [:if-mode rg-mode
    :description "Rerun"
    (3 "g" "Go" rg-rerun--transient)
    (3 "r" "Change regex" rg-rerun-change-regexp--transient)
    (3 "t" "Change literal" rg-rerun-change-literal--transient)
    (3 "f" "Change files" rg-rerun-change-files--transient)
    (3 "d" "Change directory" rg-rerun-change-dir--transient)]
   [:description "Manage"
    (4 "l" "List" rg-list-searches--transient)
    (4 "s" "Save" rg-save-search--transient)
    (4 "S" "Save as name" rg-save-search-as-name--transient)]
   [:if-mode rg-mode
    :description "History"
    (3 "b" "Back" rg-back-history--transient)
    (3 "w" "Forward" rg-forward-history--transient)]])

(eval-and-compile
  (defun rg-menu-group-at-location-p (desc loc)
    "Check if group with description DESC exist at location LOC."
    (let ((suffix (transient-get-suffix 'rg-menu loc)))
      (and suffix
           (string= (plist-get (seq-elt suffix 1) :description) desc))))

  (defun rg-menu-get-loc-of-group (desc)
    "Find the location of the group with description DESC.
Returns the transient location coordinates for the group or NIL if not found."
    (let ((loc (list 2 0)))
      (ignore-errors
        (while (not (rg-menu-group-at-location-p desc loc))
          (cl-incf (cl-second loc)))
        loc)))

  (defun rg-menu-transient-insert (group key description command)
    "Insert a new suffix into the rg-menu under GROUP.
GROUP is the description of an existing group. If the group does not exist
A new group will be created. KEY and DESCRIPTION defines the binding
and description of the new menu entry. COMMAND is a transient wrapped
command."
    (unless (stringp group)
      (user-error "'%S' is not a string" group))
    (unless (or (stringp key)
                (vectorp key))
      (user-error "'%S' should be a key description string or a key vector" key))
    (unless (stringp description)
      (user-error "'%S' is not a string" description))
    (if-let (group-loc (rg-menu-get-loc-of-group group))
        (transient-append-suffix 'rg-menu (append group-loc '(-1))
          (list 3 key description command))
      (transient-append-suffix 'rg-menu '(-1 -1)
        (vector group (list 3 key description command))))))

;;;###autoload
(defun rg-enable-menu (&optional prefix)
  "Bind `rg-menu' to PREFIX key.
If prefix is not supplied `rg-keymap-prefix' is used."
  (interactive)
  (setq prefix (or prefix rg-keymap-prefix))
  (when prefix
    (global-set-key prefix #'rg-menu)
    ;; If it's already bound it might have been rebound so keep that
    ;; instead of overriding.
    (unless (where-is-internal #'rg-menu (list rg-mode-map) t)
      (define-key rg-mode-map "m" #'rg-menu))))

(provide 'rg-menu)

;;; rg-menu.el ends here


================================================
FILE: rg-result.el
================================================
;;; rg-result.el ---- Result buffer implementation for rg.el. -*- lexical-binding: t; -*-

;; Copyright (C) 2018 David Landell <david.landell@sunnyhill.email>
;;
;; Author: David Landell <david.landell@sunnyhill.email>
;; URL: https://github.com/dajva/rg.el

;; This file is not part of GNU Emacs.

;; 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 3
;; 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., 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301, USA.

;;; Commentary:

;;; Code:

(require 'cl-lib)
(require 'grep)
(require 'mouse)
(require 'rg-header)
(require 'rg-history)
(require 'subr-x)
(require 'wgrep-rg)

;; Forward declarations.
(declare-function rg-build-command "rg.el")
(declare-function rg-get-type-aliases "rg.el")
(declare-function rg-list-searches "rg.el")
(declare-function rg-read-pattern "rg.el")
(declare-function rg-menu "rg-menu.el")


;; Customizations/public vars
(defcustom rg-use-transient-menu t
  "Use transient menu instead of a the global keymap."
  :type 'boolean
  :group 'rg
  :package-version '(rg . "2.0.0"))

(defcustom rg-show-columns nil
  "If t, show the columns of the matches in the output buffer."
  :type 'boolean
  :group 'rg)

(defcustom rg-group-result t
  "Group matches in the same file together.
If nil, the file name is repeated at the beginning of every match line."
  :type 'boolean
  :group 'rg
  :package-version '(rg . "2.0.0"))

(defcustom rg-show-header t
  "Show header in results buffer if non nil."
  :type 'boolean
  :group 'rg)

(defcustom rg-hide-command t
  "Hide most of rg command line when non nil."
  :type 'boolean
  :group 'rg)

(defcustom rg-align-position-numbers t
  "If non nil, alignment of line and column numbers is turned on."
  :type 'boolean
  :group 'rg
  :package-version '(rg . "2.0.0"))

(defcustom rg-align-line-number-field-length 4
  "Field length of aligned line numbers."
  :type 'integer
  :group 'rg)

(defcustom rg-align-column-number-field-length 3
  "Field length of aligned column numbers."
  :type 'integer
  :group 'rg)

(defcustom rg-align-line-column-separator " "
  "Separator used between line and column numbers.
Depends on `rg-show-columns'.  Default is ':'."
  :type 'string
  :group 'rg
  :package-version '(rg . "2.0.0"))

(defcustom rg-align-position-content-separator " "
  "Separator used between position numbers and the matching file content.
Default is ':'."
  :type 'string
  :group 'rg
  :package-version '(rg . "2.0.0"))

(defvar rg-filter-hook nil
  "Hook for new content in the rg buffer.
This hook is called every time the rg buffer has been updated with
new content and filtered through the `rg-filter' function.")


;; Faces
(defgroup rg-face nil
  "Settings for rg faces."
  :group 'rg)

(defface rg-match-face
  `((t :inherit ,grep-match-face))
  "Face for match highlight."
  :group 'rg-face)

(defface rg-error-face
  `((t :inherit ,grep-error-face))
  "Face for error."
  :group 'rg-face)

(defface rg-context-face
  `((t :inherit ,grep-context-face))
  "Face for context lines."
  :group 'rg-face)

(defface rg-info-face
  '((t :inherit compilation-info))
  "Face for info."
  :group 'rg-face)

(defface rg-warning-face
  '((t :inherit compilation-warning))
  "Face for warning."
  :group 'rg-face)

(defface rg-filename-face
  '((t :inherit rg-info-face))
  "Face for filename."
  :group 'rg-face)

(defface rg-file-tag-face
  '((t :inherit rg-info-face))
  "Face for file tag in grouped layout."
  :group 'rg-face)

(defface rg-line-number-face
  '((t :inherit compilation-line-number))
  "Face for line numbers."
  :group 'rg-face)

(defface rg-column-number-face
  '((t :inherit compilation-column-number))
  "Face for column numbers."
  :group 'rg-face)

(defface rg-match-position-face
  '((t :inherit default))
  "Face that is being appended to file positions.
This is the start of each matching line. This includes line number
and, depending on configuration, column number and file name."
  :group 'rg-face)


;; Internal vars and structs

(cl-defstruct (rg-search (:constructor rg-search-create)
                         (:constructor rg-search-new (pattern files dir))
                         (:copier rg-search-copy))
  pattern                ; search pattern
  files                  ; files to search
  dir                    ; base directory
  full-command           ; full-command (t or nil)
  literal                ; literal patterh (t or nil)
  flags)                 ; search specific flags

(defvar-local rg-cur-search nil
  "Stores parameters of last search.
Becomes buffer local in `rg-mode' buffers.")
(put 'rg-cur-search 'permanent-local t)

(defvar-local rg-search-history nil
  "Stores the search history per rg-mode buffer.")
(put 'rg-search-history 'permanent-local t)

(defvar-local rg-hit-count 0
  "Stores number of hits in a search.")

(defvar-local rg-match-positions nil
  "Stores position of matches in a search.
Each element is consists by (match-beginning-marker . match-string-length).")

(defvar-local rg-recompile nil
  "Is `recompile' in progress or `compile-start'.")

(defconst rg-mode-font-lock-keywords
  '(;; Command output lines.
    (": \\(.+\\): \\(?:Permission denied\\|No such \\(?:file or directory\\|device or address\\)\\)$"
     1 'rg-error-face)
    ("^rg[/a-zA-z]* started.*"
     (0 '(face nil compilation-message nil help-echo nil mouse-face nil) t))
    ("^rg[/a-zA-z]* finished \\(?:(\\([0-9]+ matches found\\))\\|with \\(no matches found\\)\\).*"
     (0 '(face nil compilation-message nil help-echo nil mouse-face nil) t)
     (1 'rg-info-face nil t)
     (2 'rg-warning-face nil t))
    ("^rg[/a-zA-z]* \\(exited abnormally\\|interrupt\\|killed\\|terminated\\)\\(?:.*with code \\([0-9]+\\)\\)?.*"
     (0 '(face nil compilation-message nil help-echo nil mouse-face nil) t)
     (1 'rg-error-face)
     (2 'rg-error-face nil t))
    ;; "filename-linenumber-" or "linenumber-" format is used for
    ;; context lines in rg
    ("^ *\\(?:.+?-\\)?[0-9]+-.*\n" (0 'rg-context-face))
    ("^.*rg \\(--color=always .*$\\)"
     (0 rg-command-line-properties)
     (1 (rg-hidden-command-line-properties)))
    ("^-\\*- mode: rg; default-directory: \"\\(.*\\)\" -\\*-$"
     (1 rg-directory-properties))
    ("\\[\\.\\.\\. [0-9]+ more match\\(es\\)*\\]$"
     (0 'rg-info-face nil t))))

(defvar rg-menu-map
  (let ((map (make-sparse-keymap "RipGrep")))
    (define-key map [rg-toggle-command-hiding]
      '(menu-item "Toggle command visibility"
                  rg-toggle-command-hiding
                  :help "Toggle showing verbose command options"))
    (define-key map [rg-enable-wgrep]
      '(menu-item "Edit buffer" wgrep-change-to-wgrep-mode
                  :help "Edit buffer and save changes."))
    (define-key map [rg-save-search]
      '(menu-item "Save search" rg-save-search-as-name
                  :help "Save current search."))
    (define-key map [rg-search-list]
      '(menu-item "List searches" rg-list-searches
                  :help "List all ripgrep search buffers."))
    (define-key map [rg-change-dir]
      '(menu-item "Change dir" rg-rerun-change-dir
                  :help "Rerun search in another directory."))
    (define-key map [rg-change-files]
      '(menu-item "Change file type" rg-rerun-change-files
                  :help "Rerun search on other file types."))
    (define-key map [rg-change-regexp]
      '(menu-item "Change regexp" rg-rerun-change-regexp
                  :help "Run regexp search with changed pattern."))
    (define-key map [rg-change-literal]
      '(menu-item "Change literal" rg-rerun-change-literal
                  :help "Run literal search with changed search string."))
    (define-key map [rg-kill-compilation]
      '(menu-item "Kill Ripgrep" kill-compilation
		  :help "Kill the currently running rg process"))
    (define-key map [rg-another]
      '(menu-item "Another search..."
                  (lambda ()
                    (interactive)
                    (rg-save-search)
                    (call-interactively 'rg))
		  :help "Save current search results and start a new search."))
    (define-key map [rg-recompile]
      '(menu-item "Go..." rg-recompile
		  :help "Rerun search"))
    map))

(defvar rg-mode-map
  (let ((map (make-sparse-keymap)))
    (set-keymap-parent map compilation-minor-mode-map)
    (define-key map " " 'scroll-up-command)
    (define-key map [?\S-\ ] 'scroll-down-command)
    (define-key map "\^?" 'scroll-down-command)
    (define-key map "\C-c\C-f" 'next-error-follow-minor-mode)
    (define-key map "\r" 'compile-goto-error)  ;; ?
    (define-key map "n" 'next-error-no-select)
    (define-key map "p" 'previous-error-no-select)
    (define-key map "{" 'compilation-previous-file)
    (define-key map "}" 'compilation-next-file)
    (define-key map "\t" 'compilation-next-error)
    (define-key map [backtab] 'compilation-previous-error)

    (define-key map "c" 'rg-rerun-toggle-case)
    (define-key map "d" 'rg-rerun-change-dir)
    (define-key map "f" 'rg-rerun-change-files)
    (define-key map "g" 'rg-recompile)
    (define-key map "i" 'rg-rerun-toggle-ignore)
    (define-key map "L" 'rg-list-searches)
    (define-key map "r" 'rg-rerun-change-regexp)
    (define-key map "s" 'rg-save-search)
    (define-key map "S" 'rg-save-search-as-name)
    (define-key map "t" 'rg-rerun-change-literal)
    (define-key map "e" 'wgrep-change-to-wgrep-mode)
    (define-key map "\M-N" 'rg-next-file)
    (define-key map "\M-P" 'rg-prev-file)
    (define-key map "\C-c>" 'rg-forward-history)
    (define-key map "\C-c<" 'rg-back-history)
    (when rg-use-transient-menu
      (define-key map "m" #'rg-menu))

    ;; Set up the menu-bar
    (define-key map [menu-bar rg]
      (cons "RipGrep" rg-menu-map))
    map)
  "The keymap for `rg-mode'.")

(defvar rg-ellipsis (if (char-displayable-p ?…) "[…]" "[...]")
  "Used when hiding command line.")

(defvar rg-finish-functions '()
  "Functions to call when a ripgrep process finishes.

Each function is called with two arguments: the compilation buffer,
and a string describing how the process finished.")


;; Defuns

(defun rg-create-mouse-map (command)
  "Create a mouse-map for the COMMAND.
This makes sure point moves to click and that the clicked window is
selected."
  (let ((map (make-sparse-keymap)))
    (define-key map [down-mouse-2] 'mouse-set-point)
    (define-key map [mouse-2] command)
    (define-key map "\C-m" command)
    map))

;; This solution was mostly copied from emacs grep.el and adjusted to
;; be more usable.
(defvar rg-command-line-properties
  (let ((map (rg-create-mouse-map 'rg-toggle-command-hiding)))
    `(face rg-context-face mouse-face highlight
           help-echo "RET, mouse-2: show unabbreviated command"
           keymap ,map))
  "Properties for graying out and keymap for hiding command line.")

(defun rg-hidden-command-line-properties ()
  "Return properties of button-like ellipsis on part of rg command line."
  (append
   '(face nil rg-command-hidden-part t)
   (when rg-hide-command
     `(display ,rg-ellipsis))))

(defun rg-toggle-command-hiding ()
  "Toggle showing the hidden part of rg command line."
  (interactive)
  (with-silent-modifications
    (let* ((beg (next-single-property-change (point-min) 'rg-command-hidden-part))
           (end (when beg
                  (next-single-property-change beg 'rg-command-hidden-part))))
      (if end
          (if (get-text-property beg 'display)
              (remove-list-of-text-properties beg end '(display))
            (add-text-properties beg end `(display ,rg-ellipsis)))
        (user-error "No abbreviated part to hide/show")))))

(defvar rg-directory-properties
  (let ((map (rg-create-mouse-map 'rg-rerun-change-dir)))
    `(face rg-filename-face mouse-face highlight
           help-echo "RET, mouse-2: Change search directory"
           keymap ,map))
  "Properties for `default-directory' in header.")

(defun rg-list-toggle (elem list)
  "Remove ELEM from LIST if present or add it if not present.
Returns the new list."
  (if (member elem list)
      (delete elem list)
    (push elem list)))

(defun rg-process-setup ()
  "Setup compilation variables and buffer for `rg'.
Set up `compilation-exit-message-function'."
  (set (make-local-variable 'compilation-exit-message-function)
       (lambda (status code msg)
         (if (eq status 'exit)
             ;; This relies on the fact that `compilation-start'
             ;; sets buffer-modified to nil before running the command,
             ;; so the buffer is still unmodified if there is no output.
             (cond ((and (zerop code) (buffer-modified-p))
                    `(,(format "finished (%d matches found)\n" rg-hit-count) . "matched"))
                   ((not (buffer-modified-p))
                    '("finished with no matches found\n" . "no match"))
                   (t
                    (cons msg code)))
           (cons msg code)))))

(defun rg-prepend-space (text length)
  "Prepend TEXT with LENGTH number of spaces."
  (let ((space-count (- length (length text))))
    (concat
     (when (> space-count 0) (make-string space-count ?\s))
     text)))

(defun rg-perform-position-numbers-alignment (line-number &optional column-number context-marker )
  "Return aligned LINE-NUMBER, COLUMN-NUMBER and CONTEXT-MARKER."
  (let* ((line-col-separator (or rg-align-line-column-separator ":"))
         (pos-content-separator (or rg-align-position-content-separator ":"))
         (pos-content-separator (if rg-show-columns
                                    pos-content-separator
                                  (propertize pos-content-separator 'invisible t)))
         (line-number-width
          (if (and rg-show-columns context-marker)
              ;; Context lines should be aligned to column numbers
              (+ rg-align-line-number-field-length
                 (1+ rg-align-column-number-field-length))
            rg-align-line-number-field-length))
         (column-number (when column-number
                          (if rg-show-columns
                              column-number
                            (propertize column-number 'invisible t)))))
    (cl-assert (if column-number (not context-marker) context-marker))
    (concat (rg-prepend-space line-number line-number-width)
            (if column-number
                (concat (if rg-show-columns
                            line-col-separator
                          pos-content-separator)
                        (rg-prepend-space column-number
                                          rg-align-column-number-field-length)
                        pos-content-separator)
              context-marker))))

(defun rg-format-line-and-column-numbers (beg end)
  "Align numbers in region defined by BEG and END."
  (goto-char beg)
  (while (re-search-forward
          "^\033\\[[0]*m\033\\[32m\\([0-9]*?\\)\033\\[[0]*m\\(:\\|-\\)\\(?:\033\\[[0]*m\\([0-9]*?\\)\033\\[[0]*m:\\)?"
          end 1)
    (let* ((line-match (match-string 1))
           (col-separator-match (match-string 2))
           (context-marker (when (equal col-separator-match "-")
                             col-separator-match))
           (column-match (match-string 3)))
    (cond
     (rg-align-position-numbers
      (replace-match
       (rg-perform-position-numbers-alignment
        line-match column-match context-marker)
       t t))
     ((and column-match (not rg-show-columns))
      (replace-match
       (propertize col-separator-match 'invisible t) t t nil 2)
      (replace-match (propertize column-match 'invisible t) t t nil 3))))))

(defun rg-filter ()
  "Handle match highlighting escape sequences inserted by the rg process.
This function is called from `compilation-filter-hook'."
  (save-excursion
    (forward-line 0)
    (let ((end (point)) beg temp-positions)
      (goto-char compilation-filter-start)
      (forward-line 0)
      (setq beg (point))
      (when (zerop rg-hit-count)
        (newline))
      ;; Only operate on whole lines so we don't get caught with part of an
      ;; escape sequence in one chunk and the rest in another.
      (when (< (point) end)
        (setq end (copy-marker end))
        ;; Add File: in front of filename
        (when rg-group-result
          (while (re-search-forward "^\033\\[[0]*m\033\\[35m\\(.*?\\)\033\\[[0]*m$" end 1)
            (replace-match (concat (propertize "File:"
                                               'rg-file-message t
                                               'face nil
                                               'font-lock-face 'rg-file-tag-face)
                                   " "
                                   (propertize (match-string 1)
                                               'face nil
                                               'font-lock-face 'rg-filename-face))
                           t t))
          (goto-char beg))

        ;; Highlight rg matches and delete marking sequences.
        (while (re-search-forward "\033\\[[0]*m\033\\[[3]*1m\033\\[[3]*1m\\(.*?\\)\033\\[[0]*m" end 1)
          (replace-match (propertize (match-string 1)
                                     'face nil 'font-lock-face 'rg-match-face)
                         t t)
          (push (cons (copy-marker (match-beginning 0))
                      (length (match-string 0)))
                temp-positions)
          (cl-incf rg-hit-count))
        (rg-format-line-and-column-numbers beg end)

        ;; Delete all remaining escape sequences
        (goto-char beg)
        (while (re-search-forward "\033\\[[0-9;]*[0mK]" end 1)
          (replace-match "" t t))

        (goto-char beg)

        (setq rg-match-positions (nconc rg-match-positions (nreverse temp-positions)))

        (run-hooks 'rg-filter-hook)))))

;; The regexp and filter functions below were taken from ag.el
;; Kudos to the people from https://github.com/Wilfred/ag.el for these.
(defconst rg-file-line-column-pattern-nogroup
  "^\\([^\n:]+?\\):\\([1-9][0-9]*\\):\\([1-9][0-9]*\\):"
  "A regexp pattern that groups output.
Groups into filename,line number and column number.")

(defun rg-file-line-column-pattern-group ()
  "A regexp pattern to match line number and column number with grouped output."
  (concat "^ *\\([1-9][0-9]*\\)"
          (regexp-quote (or (and rg-align-position-numbers
                                 rg-align-line-column-separator) ":"))
          " *\\([1-9][0-9]*\\)"
          (regexp-quote (or (and rg-align-position-numbers
                                 rg-align-position-content-separator) ":"))))

(defconst rg-file-line-pattern-nogroup
  "^\\([^\n:]+?\\):\\([1-9][0-9]*\\):"
  "A regexp pattern that groups output into filename, line number.")

(defun rg-file-line-pattern-group ()
  "A regexp pattern to match line number with grouped output."
  (concat "^ *\\([1-9][0-9]*\\)"
          (regexp-quote (or (and rg-align-position-numbers
                                 rg-align-position-content-separator) ":"))))

(defun rg-match-grouped-filename ()
  "Match filename backwards when a line/column match is found."
  (save-match-data
    (save-excursion
      (when (re-search-backward "^File: \\(.*\\)$" (point-min) t)
        (list (match-string 1))))))

(defun rg-set-compilation-error-regexps ()
  "Set the compilation mode regexps for errors for rg-mode buffers."
  (set (make-local-variable 'compilation-error-regexp-alist)
       '(rg-group-with-column
         rg-nogroup-with-column
         rg-group-no-column
         rg-nogroup-no-column))
  (set (make-local-variable 'compilation-error-regexp-alist-alist)
       (list (cons 'rg-nogroup-no-column (list rg-file-line-pattern-nogroup 1 2))
             (cons 'rg-nogroup-with-column (list rg-file-line-column-pattern-nogroup 1 2 3))
             (cons 'rg-group-with-column (list (rg-file-line-column-pattern-group) 'rg-match-grouped-filename 1 2))
             (cons 'rg-group-no-column (list (rg-file-line-pattern-group) 'rg-match-grouped-filename 1)))))

(define-compilation-mode rg-mode "rg"
  "Major mode for `rg' search results.
Commands:
\\<rg-mode-map>
\\[rg-rerun-change-dir]\t Repeat this search in another directory (`rg-rerun-change-dir').
\\[rg-rerun-change-files]\t Repeat this search with another file pattern (`rg-rerun-change-files').
\\[rg-rerun-change-regexp]\t Change the search regexp for the current search (`rg-rerun-change-regexp').
\\[rg-rerun-change-literal]\t Change the search literal for the current search (`rg-rerun-change-literal').
\\[rg-rerun-toggle-ignore]\t Repeat search with toggled '--no-ignore' flag (`rg-rerun-toggle-ignore').
\\[rg-rerun-toggle-case]\t Repeat search with toggled case insensitive setting (`rg-rerun-toggle-case').
\\[rg-save-search-as-name]\t Save search result, prompt for new name (`rg-save-search-as-name').
\\[rg-save-search]\t Save search result to some unique name (`rg-save-search').
\\[wgrep-change-to-wgrep-mode]\t Change mode to `wgrep'.

\\{rg-mode-map}"
  (set (make-local-variable 'tool-bar-map) grep-mode-tool-bar-map)
  (set (make-local-variable 'compilation-error-face) 'rg-filename-face)
  (set (make-local-variable 'compilation-message-face) 'rg-match-position-face)
  (set (make-local-variable 'compilation-line-face) 'rg-line-number-face)
  (set (make-local-variable 'compilation-column-face) 'rg-column-number-face)

  ;; compilation-directory-matcher can't be nil, so we set it to a regexp that
  ;; can never match.
  (set (make-local-variable 'compilation-directory-matcher) '("\\`a\\`"))
  (set (make-local-variable 'compilation-process-setup-function)
       'rg-process-setup)
  (set (make-local-variable 'compilation-disable-input) t)
  (set (make-local-variable 'compilation-error-screen-columns) nil)
  (unless rg-search-history
    (setq rg-search-history (rg-history-create)))
  (set (make-local-variable 'compilation-filter-hook) '(rg-filter))
  ;; Set compilation error regexps as the last compilation-mode-hook to be
  ;; able to override these if they were set by other hooks.
  (add-hook 'compilation-mode-hook
            'rg-set-compilation-error-regexps 90 'local))

(defun rg-maybe-show-header ()
  "Recreate header if enabled."
  (when rg-show-header
    (rg-create-header-line 'rg-cur-search
                           (rg-search-full-command rg-cur-search))))

(defun rg-mode-init (search)
  "Initiate `rg-mode' with SEARCH in current buffer."
  (unless (eq major-mode 'rg-mode)
    (error "Function rg-mode-init called in non rg mode buffer"))
  (hack-dir-local-variables-non-file-buffer)
  (setq rg-cur-search search)
  (rg-history-push (rg-search-copy rg-cur-search)
                   rg-search-history)
  (rg-maybe-show-header)
  (rg-configure-imenu))

(defun rg-recompile ()
  "Rerun the current search."
  (interactive)
  (let ((rg-recompile t))
    (recompile))
  (hack-dir-local-variables-non-file-buffer)
  (rg-maybe-show-header)
  (rg-configure-imenu))

(defun rg-rerun (&optional no-history)
  "Run `recompile' with `compilation-arguments' taken from `rg-cur-search'.
If NO-HISTORY is non nil skip adding the search to the search history."
  (let ((pattern (rg-search-pattern rg-cur-search))
        (files (rg-search-files rg-cur-search))
        (dir (rg-search-dir rg-cur-search))
        (literal (rg-search-literal rg-cur-search))
        (flags (rg-search-flags rg-cur-search)))
    ;; compilation-directory is used as search dir and
    ;; default-directory is used as the base for file paths.
    (setq compilation-directory dir)
    (setq default-directory compilation-directory)
    (setcar compilation-arguments
            (or (rg-search-full-command rg-cur-search)
                (rg-build-command pattern files literal flags)))
    (unless no-history
      (rg-history-push (rg-search-copy rg-cur-search)
                       rg-search-history))
    (rg-recompile)))

(defun rg-navigate-file-message (pos limit direction)
  "Return position of next 'rg-file-message text property.
POS is the start position of the search and LIMIT is the limit of the
search.  If the property is not found within LIMIT, LIMIT is returned.  If
DIRECTION is positive search forward in the buffer, otherwise search
backward."
  (let ((prop-change-func
         (if (> direction 0)
             'next-single-property-change
           'previous-single-property-change)))
    (while
        (progn
          (setq pos (funcall prop-change-func pos 'rg-file-message nil limit))
          (and (not (eq pos limit))
               (not (get-text-property pos 'rg-file-message)))))
    pos))

(defun rg-navigate-file-group (steps)
  "Move point to the a matched result group in the compilation buffer.
STEPS decides how many groups to move past.  Negative value means
backwards and positive means forwards."
  (let (move-to
        (pos (point))
        (steps-left (abs steps))
        (limit
         (if (< steps 0)
             (point-min)
           (point-max))))
    (while  (and (> steps-left 0) (not (equal pos limit)))
      (setq pos (rg-navigate-file-message pos limit steps))
      (unless (eq pos limit)
        (setq move-to pos))
      (setq steps-left (- steps-left 1)))
    (when move-to
      (goto-char move-to))))

(defun rg-rerun-toggle-flag (flag)
  "Toggle FLAG in `rg-cur-search`."
  (setf (rg-search-flags rg-cur-search)
        (rg-list-toggle flag (rg-search-flags rg-cur-search)))
  (rg-rerun))

(defun rg-rerun-toggle-case ()
  "Rerun last search with toggled case sensitivity setting."
  (interactive)
  (rg-rerun-toggle-flag "-i"))

(defun rg-rerun-toggle-ignore ()
  "Rerun last search with toggled '--no-ignore' flag."
  (interactive)
  (rg-rerun-toggle-flag "--no-ignore"))

(defun rg-rerun-toggle-rexexp-literal ()
  "Switch between literal and regexp and rerun last search."
  (interactive)
  (setf (rg-search-literal rg-cur-search)
        (not (rg-search-literal rg-cur-search)))
  (rg-rerun))

(defun rg-rerun-change-query ()
  "Rerun last search and change search string."
  (interactive)
  (rg-rerun-change-search-string
   (rg-search-literal rg-cur-search)))

(defun rg-rerun-change-search-string (literal)
  "Rerun last search but prompt for new search pattern.
IF LITERAL is non nil this will trigger a literal search,
otherwise a regexp search."
  (let ((pattern (rg-search-pattern rg-cur-search))
        (read-from-minibuffer-orig (symbol-function 'read-from-minibuffer)))
    ;; Override read-from-minibuffer in order to insert the original
    ;; pattern in the input area.
    (cl-letf (((symbol-function #'read-from-minibuffer)
               (lambda (prompt &optional _ &rest args)
                 (apply read-from-minibuffer-orig prompt pattern args))))
      (setf (rg-search-pattern rg-cur-search) (rg-read-pattern literal pattern)))
    (setf (rg-search-literal rg-cur-search) literal)
    (rg-rerun)))

(defun rg-rerun-change-regexp ()
  "Rerun last search but prompt for new regexp."
  (interactive)
  (rg-rerun-change-search-string nil))

(defun rg-rerun-change-literal ()
  "Rerun last search but prompt for new literal."
  (interactive)
  (rg-rerun-change-search-string t))

(defun rg-rerun-change-files()
  "Rerun last search but prompt for new files."
  (interactive)
  (let ((files (rg-search-files rg-cur-search)))
    (setf (rg-search-files rg-cur-search)
          (completing-read
           (concat "Repeat search in files (default: [" files "]): ")
           (rg-get-type-aliases)
           nil nil nil 'rg-files-history
           files))
    (rg-rerun)))

(defun rg-rerun-change-dir()
  "Rerun last search but prompt for new dir."
  (interactive)
  (setf (rg-search-dir rg-cur-search)
        (read-directory-name "In directory: "
                             (rg-search-dir rg-cur-search) nil))
  (rg-rerun))

(defun rg-next-file (n)
  "Move point to next file's first match.
Prefix arg N decides how many files to navigate.  When
`rg-group-result' is nil this is the same as invoking
`compilation-next-file', otherwise this will navigate to the
next file with grouped matches."
  (interactive "p")
  (if rg-group-result
      (when (rg-navigate-file-group n)
        (forward-line))
    (compilation-next-file n)))

(defun rg-prev-file (n)
  "Move point to previous file's first match.
Prefix arg N decides how many files to navigate.  When
`rg-group-result' is nil this is the same as invoking
`compilation-previous-file', otherwise this will navigate to the
previous file with grouped matches."
  (interactive "p")
  (if rg-group-result
      (let ((steps
             ;; On match rows we move 2 steps back to get to previous
             ;; file, otherwise 1 step.  The later is on file
             ;; headings, space between files and at the end of search results.
             (if (or (get-text-property (point) 'rg-file-message)
                     (save-excursion
                       (beginning-of-line)
                       (looking-at "^\\(?:rg finished .*\\)*$")))
                 n
               (+ n 1))))
        (when (rg-navigate-file-group (- steps))
          (forward-line)))
    (compilation-previous-file n)))

(defun rg-back-history ()
  "Navigate back in the search history."
  (interactive)
  (if-let (prev (rg-history-back rg-search-history))
      (progn
        (setq rg-cur-search (rg-search-copy prev))
        (rg-rerun 'no-history))
    (message "No more history elements for back.")))

(defun rg-forward-history ()
  "Navigate forward in the search history."
  (interactive)
  (if-let (next (rg-history-forward rg-search-history))
      (progn
        (setq rg-cur-search (rg-search-copy next))
        (rg-rerun 'no-history))
    (message "No more history elements for forward.")))

(defun rg-configure-imenu ()
  "Add files with matches to imenu if rg-group-result is enabled."
  (when rg-group-result
    (setq imenu-create-index-function
          (lambda ()
            (goto-char (point-min))
            (let ((elements nil)
                  (filepath nil)
                  (nextfile (point-min)))
              (while (setq nextfile (rg-navigate-file-message nextfile nil 1))
                (save-excursion
                  (goto-char nextfile)
                  (and (looking-at-p "^File: ") (forward-char 6))
                  (setq filepath (buffer-substring-no-properties (point) (line-end-position))))
                (push (cons filepath nextfile) elements))
              (nreverse elements))))))

(defun rg-cur-search-pattern ()
  "Get the current search pattern."
  (rg-search-pattern rg-cur-search))

(provide 'rg-result)

;; Local Variables:
;; byte-compile-warnings: (not docstrings)
;; End:

;;; rg-result.el ends here


================================================
FILE: rg.el
================================================
;;; rg.el --- A search tool based on ripgrep -*- lexical-binding: t; -*-

;; Copyright (C) 1985-1987, 1993-1999, 2001-2015 Free Software
;; Foundation, Inc.
;; Copyright (C) 2016-2018 David Landell <david.landell@sunnyhill.email>
;;
;; Author: David Landell <david.landell@sunnyhill.email>
;;         Roland McGrath <roland@gnu.org>
;; Version: 2.4.1
;; URL: https://github.com/dajva/rg.el
;; Package-Requires: ((emacs "28.1") (transient "0.9.2") (wgrep "2.1.10"))
;; Keywords: matching, tools

;; This file is not part of GNU Emacs.

;; 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 3
;; 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., 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301, USA.

;;; Commentary:

;; A search package based on the ripgrep command line tool.
;; It allows you to interactively create searches, doing automatic
;; searches based on the editing context, refining and modifying
;; search results and much more.  It is also highly configurable to be
;; able to fit different users' needs.

;; If you are used to built-in Emacs rgrep command, transitioning to
;; rg should be simple.  rg provides a lot of extra features
;; but the basics are similar.
;;
;; The big benefit of using ripgrep instead of grep as a backend is
;; speed.  Especially when searching large source code repositories
;; where ripgrep really shines.

;; See info node `(rgel)Top' for documentation or online at https://rgel.readthedocs.io.


;;; Code:

(require 'cl-lib)
(require 'cus-edit)
(require 'grep)
(require 'rg-ibuffer)
(require 'rg-menu)
(require 'rg-result)
(require 'rg-info-hack)
(require 'subr-x)
(require 'vc)
(require 'files-x)


;; Customizations/public vars
(defgroup rg nil
  "Settings for rg."
  :group 'tools
  :group 'external)

(defcustom rg-custom-type-aliases
  '()
  "A list of file type aliases that are added to the ripgrep built in aliases.
Each list element may be a (string . string) cons containing the name of the
type alias and the file patterns, or a lambda returning a similar cons cell.
A lambda should return nil if it currently has no type aliases to contribute."
  :type '(repeat (choice (cons string string) function))
  :group 'rg)

(defcustom rg-prioritized-type-aliases '()
  "A list of file type aliases that are prioritized.
When detecting the file type from the current buffer these aliases are selected
if there are conflicting aliases for a file type.  Contains only the alias names
and need to match alias names of ripgrep's built in aliases.  The order of the
list decides the priority among the types in the list."
  :type '(repeat string)
  :group 'rg)

(defcustom rg-executable (executable-find "rg")
  "Ripgrep executable."
  :type 'string
  :group 'rg)

(defcustom rg-executable-per-connection t
  "Invoke `executable-find' per host and store as connection local variable.
Only works in Emacs 27.1 or later."
  :type 'boolean
  :group 'rg)

(defcustom rg-command-line-flags nil
  "List of command line flags for rg.
Alternatively a function returning a list of flags."
  :type '(choice function (repeat string))
  :group 'rg)

(defcustom rg-ignore-case 'case-fold-search
  "Decides which mode of case insensitive search that is enabled.
CASE-FOLD-SEARCH means that the variable `case-fold-search' will
trigger smart-case functionality if non nil.
SMART means that case insensitive search will be triggered if the
search pattern contains only lower case.  If the pattern contains upper
case letters, case sensitive search will be performed.  This is similar
to the rg '--smart-case' flag.
FORCE will force case insensitive search regardless of the content of
the search pattern.
NIL means case sensitive search will be forced."
  :type '(choice (const :tag "Case Fold Search" case-fold-search)
                 (const :tag "Smart" smart)
                 (const :tag "Force" force)
                 (const :tag "Off" nil))
  :group 'rg)

;;;###autoload
(defcustom rg-keymap-prefix "\C-cs"
  "Prefix for global `rg' keymap."
  :type 'key-sequence
  :group 'rg)

(defcustom rg-default-alias-fallback "everything"
  "The default file alias to use when no alias can be determined.
This must be a string that can be match against the types returned
from `rg-get-type-aliases'."
  :type 'string
  :group 'rg)

(defcustom rg-buffer-name "rg"
  "Search results buffer name.
Can be string or function."
  :type '(choice string function)
  :group 'rg)

(defcustom rg-ignore-ripgreprc t
  "Ignore the ripgrep config file.
Disabling this setting can break functionality of this package."
  :type 'boolean
  :group 'rg)

(defcustom rg-w32-unicode nil
  "Enable Unicode support on Windows.
A workaround for NTEmacs subprocess not supporting Unicode arguments."
  :type 'boolean
  :group 'rg)

(defcustom rg-w32-ripgrep-proxy
  (expand-file-name "rg-w32-ripgrep-proxy.bat" user-emacs-directory)
  "An automatically generated temporary batch file.
Used to proxy ripgrep Unicode arguments."
  :type 'string
  :group 'rg)

;;;###autoload
(defvar rg-command-line-flags-function 'identity
  "Function to modify command line flags of a search.
The argument of the function is an optional list of search specific
command line flags and the function shall return a list of command
line flags to use.")


;; Internal vars and structs
(defvar rg-builtin-type-aliases-cache nil
  "Cache for \"rg --type-list\".")

(defvar rg-prioritized-type-aliases-cache nil
  "Cache for `rg-prioritized-type-aliases'.")

(defvar rg-initial-toggle-flags nil
  "List of command line flags set by default by `rg-define-toggle' macro.")

(defvar rg-history nil "History for full rg commands.")
(defvar rg-files-history nil "History for files args.")
(defvar rg-pattern-history nil "History for search patterns.")

(defvar-local rg--executable-local 'unknown)

(defvar rg-required-command-line-flags
  '("--color=always"
    "--colors=match:fg:red"
    "--colors=path:fg:magenta"
    "--colors=line:fg:green"
    "--colors=column:none"
    "-n"))

(defconst rg-internal-type-aliases
  '(("all" . "all defined type aliases") ; rg --type=all
    ("everything" . "*")) ; rg without '--type' arg
  "Internal type aliases for special purposes.
These are not produced by \"rg --type-list\" but we need them anyway.")

(defvar rg-global-map
  (let ((map (make-sparse-keymap)))
    (define-key map "d" 'rg-dwim)
    (define-key map "k" 'rg-kill-saved-searches)
    (define-key map "l" 'rg-list-searches)
    (define-key map "p" 'rg-project)
    (define-key map "r" 'rg)
    (define-key map "s" 'rg-save-search)
    (define-key map "S" 'rg-save-search-as-name)
    (define-key map "t" 'rg-literal)
    map)
  "The global keymap for `rg'.")


;; Defuns
(defun rg-has-connection-local-executable (criteria)
  "Return non nil if there is a connection local executable for HOST."
  (when (and (fboundp 'hack-connection-local-variables)
             (boundp 'connection-local-variables-alist))
    (hack-connection-local-variables criteria)
    (assoc 'rg-executable connection-local-variables-alist)))

(defun rg-find-executable ()
  "Determine which rg executable to use."
  (let* ((remote-host (file-remote-p default-directory 'host))
         (criteria `(:application rg :machine ,remote-host)))
    (if (and remote-host
             rg-executable-per-connection
             ;; Below are just to make byte compiler happy
             (fboundp 'connection-local-set-profile-variables)
             (fboundp 'connection-local-set-profiles)
             (fboundp 'hack-connection-local-variables-apply)
             (fboundp 'with-connection-local-variables))
        (progn
          ;; Find executable on remote host once
          (when (not (rg-has-connection-local-executable criteria))
            (let ((rg-vars-symbol (intern (concat "rg-vars-" remote-host)))
                  (rg-exec (with-no-warnings (executable-find "rg" t))))
              (connection-local-set-profile-variables
               rg-vars-symbol
               `((rg-executable . ,rg-exec)))
              (connection-local-set-profiles criteria rg-vars-symbol)))
          ;; Here there should be a remote executable available if found
          (hack-connection-local-variables-apply criteria)
          rg-executable)
      ;; Use local executable for local buffer
      (default-value 'rg-executable))))

(defun rg-executable ()
  "Return the \"rg\" executable.
Raises an error if it can not be found."
  (let ((executable (rg-find-executable)))
    (if executable
        (shell-quote-argument executable)
      (user-error "No 'rg' executable found in host %s"
                  (or (file-remote-p default-directory 'host) "localhost")))))

(defun rg--buffer-name ()
  "Wrapper for variable `rg-buffer-name'.  Return string or call function."
  (if (functionp rg-buffer-name)
      (funcall rg-buffer-name)
    rg-buffer-name))

(defun rg-buffer-name (&optional name-of-mode)
  "Return search results buffer name.
NAME-OF-MODE is needed to pass this function to `compilation-start'."
  (ignore name-of-mode)
  (if rg-recompile
      (buffer-name)
    (format "*%s*" (rg--buffer-name))))

(defun rg-build-type-add-args ()
  "Build a list of --type-add: \"foo:*.foo\" flags.
Do this for each type in `rg-custom-type-aliases'."
  (mapcar
   (lambda (typedef)
     (let ((name (car typedef))
           (globs (cdr typedef)))
       (mapconcat
        (lambda (glob)
          (concat "--type-add="
                  (shell-quote-argument (concat name ":" glob))))
        (split-string globs) " ")))
   (rg-get-custom-type-aliases)))

(defun rg-is-custom-file-pattern (files)
  "Return non nil if FILES is a custom file pattern."
  (not (assoc files (rg-get-type-aliases))))

(defun rg-build-command (pattern files literal flags)
  "Create the command line for PATTERN and FILES.
LITERAL determines if search will be literal or regexp based and FLAGS
are command line flags to use for the search."
  (let ((command-line
         (append
          rg-required-command-line-flags
          (when (or rg-show-columns rg-group-result)
            (list "--column"))
          (rg-build-type-add-args)
          (if (functionp rg-command-line-flags)
              (funcall rg-command-line-flags)
            rg-command-line-flags)
          flags

          (list
           (if rg-group-result "--heading" "--no-heading"))
          (when rg-ignore-ripgreprc
            (list "--no-config"))
          (when (rg-is-custom-file-pattern files)
            (list (concat "--type-add=" (shell-quote-argument (concat "custom:" files)))))
          (when literal
            (list "--fixed-strings"))
          (when (not (equal files "everything"))
            (list "--type=<F>"))
          (list "-e <R>")
          (when (member system-type '(darwin windows-nt))
            (list ".")))))

    (let ((command (grep-expand-template
                    (mapconcat 'identity (cons (rg-executable) (delete-dups command-line)) " ")
                    pattern
                    (if (rg-is-custom-file-pattern files) "custom" files))))
      (cond ((and (eq system-type 'windows-nt) rg-w32-unicode)
             (with-temp-file rg-w32-ripgrep-proxy
               (set-buffer-multibyte t)
               (setq buffer-file-coding-system 'utf-8-dos)
               (insert (format "@echo off\n"))
               (insert (format "chcp 65001 > nul\n"))
               (insert (format "%s\n" command)))
             rg-w32-ripgrep-proxy)
            (t command)))))

(defun rg-invoke-rg-type-list ()
  "Invokes rg --type-list and return the result."
  (shell-command-to-string (concat (rg-executable) " --type-list")))

(defun rg-list-builtin-type-aliases ()
  "Invokes rg --type-list and puts the result in an alist."
  (let ((type-list (delete "" (split-string (rg-invoke-rg-type-list) "\n"))))
    (mapcar
     (lambda (type-alias)
       (setq type-alias (split-string type-alias ":" t))
       (cons (string-trim (car type-alias))
             (string-trim
              (mapconcat 'identity
                         (split-string (cadr type-alias) "," t )
                         " "))))
     type-list)))


(defun rg-get-custom-type-aliases ()
  "Get alist of custom type aliases.
Any lambda elements will be evaluated, and nil results will be
filtered out."
  (delq nil (mapcar
             (lambda (ct) (if (functionp ct) (funcall ct) ct))
             rg-custom-type-aliases)))

(defun rg-get-type-aliases (&optional skip-internal)
  "Return supported type aliases.
If SKIP-INTERNAL is non nil the `rg-internal-type-aliases' will be
excluded."
  ;; Read from ripgrep once or if prioritized aliases changed.
  (unless (and rg-builtin-type-aliases-cache
               (equal rg-prioritized-type-aliases
                      (mapcar #'car rg-prioritized-type-aliases-cache)))
    (let ((builtin-aliases (rg-list-builtin-type-aliases)))
      (if rg-prioritized-type-aliases
          (progn
            (let ((prioritized-type-aliases
                   (seq-filter (lambda (item)
                                 (member (car item) rg-prioritized-type-aliases))
                               builtin-aliases)))
              ;; Reorder the the found aliases to the same order as rg-prioritized-type-aliases
              (setq rg-prioritized-type-aliases-cache
                    (seq-map (lambda (item)
                               (assoc item prioritized-type-aliases))
                             rg-prioritized-type-aliases))
              ;; Remove the prioritzed aliases from the builtin cache
              ;; to avoid duplicates.
              (setq rg-builtin-type-aliases-cache
                    (seq-remove (lambda (item)
                                  (member (car item) rg-prioritized-type-aliases))
                                builtin-aliases))))
        ;; Simple case, just assign
        (setq rg-builtin-type-aliases-cache builtin-aliases)
        (setq rg-prioritized-type-aliases-cache nil))))
  (append (rg-get-custom-type-aliases)
          rg-prioritized-type-aliases-cache
          rg-builtin-type-aliases-cache
          (unless skip-internal rg-internal-type-aliases)))

(defun rg-default-alias ()
  "Return the default alias by matching alias globs with the buffer file name."
  (let* ((bufname (or (buffer-file-name)
                      (replace-regexp-in-string "<[0-9]+>\\'" "" (buffer-name))))
         (filename (and bufname
                        (stringp bufname)
                        (file-name-nondirectory bufname))))
    (or
     (when filename
       (cl-find-if
        (lambda (alias)
          (string-match (mapconcat 'wildcard-to-regexp
                                   (split-string (cdr alias) nil t)
                                   "\\|")
                        filename))
        (rg-get-type-aliases t)))
     ;; Default when an alias for the file can't be determined
     (or
      (cl-find-if
       (lambda (alias)
         (string= rg-default-alias-fallback (car alias)))
       (rg-get-type-aliases))
      (progn
        (message "Warning: rg-default-alias-fallback customization does not match any alias. Using \"all\".")
        (car rg-internal-type-aliases))))))

(defun rg-tag-default ()
  "Get the marked area or thing at point.
Returns nil if nothing at point."
  (or (and transient-mark-mode mark-active
	   (/= (point) (mark))
	   (buffer-substring-no-properties (point) (mark)))
      (funcall (or find-tag-default-function
		   (get major-mode 'find-tag-default-function)
		   'find-tag-default))))

(defun rg-read-files ()
  "Read files argument for interactive rg."
  (let ((default-alias (rg-default-alias)))
    (completing-read
     (concat "Search in files"
             (if default-alias
                 (concat
                  " (default: [" (car default-alias) "] = "
                  (cdr default-alias) ")"))
             ": ")
     (rg-get-type-aliases)
     nil nil nil 'rg-files-history
     (car default-alias))))

(defun rg-read-pattern (literal &optional default)
  "Read search pattern argument from user.
If LITERAL is non nil prompt for literal string.
DEFAULT is the default pattern to use at the prompt."
  (let ((default (or default (rg-tag-default)))
        (prompt (concat (if literal "Literal" "Regexp")
                        " search for")))
    (read-regexp prompt default 'rg-pattern-history)))

(defun rg-project-root (file)
  "Find the project root of the given FILE."
  (or
   (when (and (require 'projectile nil t)
              (fboundp 'projectile-project-root))
     (projectile-project-root))
   (when (and (require 'find-file-in-project nil t)
              (fboundp 'ffip-project-root))
     (ffip-project-root))
   (when (and (require 'project nil t)
              (fboundp 'project-current))
     (if-let ((project (project-current)))
         (cond
          ((fboundp 'project-root)
           (project-root project))
          ((fboundp 'project-roots)
           (car (project-roots project))))))
   (let ((file (expand-file-name (or file default-directory))))
     (condition-case nil
         (vc-call-backend (vc-responsible-backend file) 'root file)
       (error (file-name-directory file))))))

(defun rg-run (pattern files dir &optional literal confirm flags)
  "Execute rg command with supplied PATTERN, FILES and DIR.
If LITERAL is nil interpret PATTERN as regexp, otherwise as a literal.
CONFIRM allows the user to confirm and modify the command before
executing.  FLAGS is additional command line flags to use in the search."
  (unless (and (stringp pattern) (> (length pattern) 0))
    (signal 'user-error '("Empty string: No search done")))
  (wgrep-rg-warn-ag-setup)
  (unless (and (file-directory-p dir) (file-readable-p dir))
    (setq dir default-directory))
  (rg-apply-case-flag pattern)
  (setq dir (file-name-as-directory (expand-file-name dir)))
  (let* ((flags (append rg-initial-toggle-flags flags))
         (default-directory dir)
         (command (rg-build-command
                   pattern files literal
                   flags))
         confirmed)
    (if confirm
        (setq confirmed
              (read-from-minibuffer "Confirm: "
                                    command nil nil 'rg-history))
      (add-to-history 'rg-history command))
    (let ((search (rg-search-create
                   :pattern pattern
                   :files files
                   :dir dir
                   :literal literal
                   :flags flags)))
      (when (and confirmed
                 (not (string= confirmed command)))
        (setq command confirmed)
        ;; If user changed command we can't know the parts of the
        ;; search and needs to disable result buffer modifications.
        (setf (rg-search-full-command search) command))
      ;; Since `rg-buffer-name' can be changed through dir-locals file we
      ;; need to apply variables from dir-locals that resides in search dir.
      ;; This way the results buffer will receive correct name on `compilation-start'.
      ;; `hack-dir-local-variables' is searching dir-locals file in
      ;; `buffer-file-name' or `default-directory' directory.
      ;; Temporary buffer must be created here to make sure that dir-locals
      ;; file is loaded from `default-directory' defined above and
      ;; not from `buffer-file-name' in case search is started from file buffer.
      (with-temp-buffer
        (hack-dir-local-variables-non-file-buffer)
        ;; Setting process-setup-function makes exit-message-function work
        ;; even when async processes aren't supported.
        (with-current-buffer (compilation-start command 'rg-mode #'rg-buffer-name)
          (rg-mode-init search)))))
  (if (eq next-error-last-buffer (current-buffer))
      (setq default-directory dir)))

(defun rg-apply-case-flag (pattern)
  "Make sure -i is added to the command if needed.
The value of the `rg-ignore-case' variable and the case of the
supplied PATTERN influences the result.  See `rg-ignore-case' for mor
Download .txt
gitextract_p8leny0j/

├── .ert-runner
├── .github/
│   └── workflows/
│       ├── build.yml
│       └── documentation.yml
├── .gitignore
├── Cask
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── docs/
│   ├── configuration.org
│   ├── contribute.org
│   ├── gpl.org
│   ├── index.org
│   ├── org-bootstrap.el
│   ├── rst/
│   │   ├── Makefile
│   │   ├── conf.py
│   │   └── elispdomain.py
│   ├── usage.org
│   └── utils.org
├── rg-header.el
├── rg-history.el
├── rg-ibuffer.el
├── rg-info-hack.el
├── rg-isearch.el
├── rg-menu.el
├── rg-result.el
├── rg.el
├── rgel.info
├── test/
│   ├── data/
│   │   ├── bar.baz
│   │   ├── bar.el
│   │   ├── context.el
│   │   ├── dirlocals/
│   │   │   └── .dir-locals.el
│   │   ├── foo.baz
│   │   ├── foo.el
│   │   └── limenu.el
│   ├── package-bootstrap.el
│   ├── rg-header.el-test.el
│   ├── rg-history.el-test.el
│   ├── rg-isearch.el-test.el
│   ├── rg-menu.el-test.el
│   ├── rg.el-test.el
│   ├── style-check.el
│   ├── test-helper.el
│   └── wgrep-rg.el-test.el
└── wgrep-rg.el
Download .txt
SYMBOL INDEX (19 symbols across 1 files)

FILE: docs/rst/elispdomain.py
  class ELispMarkup (line 17) | class ELispMarkup(ObjectDescription):
    method add_target_and_index (line 18) | def add_target_and_index(self, name, sig, signode):
  class ELispFunction (line 40) | class ELispFunction(ELispMarkup):
    method get_index_text (line 41) | def get_index_text(self, objectname, name):
    method handle_signature (line 44) | def handle_signature(self, sig, signode):
  class ELispVariable (line 62) | class ELispVariable(ELispMarkup):
    method get_index_text (line 63) | def get_index_text(self, objectname, name):
    method handle_signature (line 66) | def handle_signature(self, sig, signode):
  class ELispCommand (line 71) | class ELispCommand(ELispMarkup):
    method get_index_text (line 76) | def get_index_text(self, objectname, name):
    method handle_signature (line 79) | def handle_signature(self, sig, signode):
  class ELispOption (line 91) | class ELispOption(ELispMarkup):
    method get_index_text (line 96) | def get_index_text(self, objectname, name):
    method handle_signature (line 99) | def handle_signature(self, sig, signode):
  class ELispDomain (line 109) | class ELispDomain(Domain):
    method clear_doc (line 136) | def clear_doc(self, docname):
    method resolve_xref (line 141) | def resolve_xref(self, env, fromdocname, builder, type_, target, node,
    method get_objects (line 152) | def get_objects(self):
  function setup (line 157) | def setup(app):
Condensed preview — 45 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (433K chars).
[
  {
    "path": ".ert-runner",
    "chars": 5,
    "preview": "-L .\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 2339,
    "preview": "name: Build\non:\n  push:\n  release:\n    types:\n      - created\n  pull_request:\n  schedule:\n    - cron: '0 6 1 * *'\njobs:\n"
  },
  {
    "path": ".github/workflows/documentation.yml",
    "chars": 2386,
    "preview": "name: Documentation\non:\n  push:\n  release:\n    types:\n      - created\njobs:\n  documentation:\n    runs-on: ubuntu-latest\n"
  },
  {
    "path": ".gitignore",
    "chars": 21,
    "preview": ".cask/*\ndist/*\n*.elc\n"
  },
  {
    "path": "Cask",
    "chars": 511,
    "preview": "(source gnu)\n(source melpa)\n\n(package-file \"rg.el\")\n\n(files\n \"rg.el\"\n \"rg-history.el\"\n \"rg-result.el\"\n \"rg-header.el\"\n \""
  },
  {
    "path": "Dockerfile",
    "chars": 1103,
    "preview": "FROM ubuntu\nSHELL [\"/bin/bash\", \"-c\"]\n\nRUN apt-get -y update\n\n# noninteractive is needed to avoid config of tzlocal pack"
  },
  {
    "path": "LICENSE",
    "chars": 35147,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "Makefile",
    "chars": 3209,
    "preview": "EMACS_VERSION=29-4\nDOCKER_IMAGE=rg.el-test-emacs-$(EMACS_VERSION)\n\nifdef USE_DOCKER\nDOCKER_WRAPPER=docker run --workdir "
  },
  {
    "path": "README.md",
    "chars": 2695,
    "preview": "# rg.el\n\n[![License GPL 3](https://img.shields.io/badge/license-GPL_3-green.svg?style=flat)](LICENSE)\n[![MELPA Stable](h"
  },
  {
    "path": "docs/configuration.org",
    "chars": 20612,
    "preview": "#+TITLE: Configuration\n#+AUTHOR: David Landell\n#+EMAIL: david.landell@sunnyhill.email\n#+DATE: 2019\n#+LANGUAGE: en\n#+OPTI"
  },
  {
    "path": "docs/contribute.org",
    "chars": 4969,
    "preview": "#+TITLE: Contribute\n#+AUTHOR: David Landell\n#+EMAIL: david.landell@sunnyhill.email\n#+DATE: 2019\n#+LANGUAGE: en\n#+OPTIONS"
  },
  {
    "path": "docs/gpl.org",
    "chars": 290,
    "preview": "#+TITLE: GNU General Public License\n#+AUTHOR: David Landell\n#+EMAIL: david.landell@sunnyhill.email\n#+DATE: 2019\n#+LANGUA"
  },
  {
    "path": "docs/index.org",
    "chars": 1845,
    "preview": "#+TITLE: Rg Manual\n#+AUTHOR: David Landell\n#+EMAIL: david.landell@sunnyhill.email\n#+DATE: 2019\n#+LANGUAGE: en\n#+OPTIONS:"
  },
  {
    "path": "docs/org-bootstrap.el",
    "chars": 3462,
    "preview": ";;; org-bootstrap.el --- Description -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2019 David Landell <david.landell@sun"
  },
  {
    "path": "docs/rst/Makefile",
    "chars": 580,
    "preview": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHI"
  },
  {
    "path": "docs/rst/conf.py",
    "chars": 5581,
    "preview": "# -*- coding: utf-8 -*-\n#\n# Configuration file for the Sphinx documentation builder.\n#\n# This file does only contain a s"
  },
  {
    "path": "docs/rst/elispdomain.py",
    "chars": 4886,
    "preview": "# -*- coding: utf-8 -*-\n\"\"\"\nEmacs Lisp Domain for Sphinx\n\nCopyright 2014 by Jorgen Schäfer\n\n\"\"\"\n\nfrom sphinx import addn"
  },
  {
    "path": "docs/usage.org",
    "chars": 26321,
    "preview": "#+TITLE: Usage\n#+AUTHOR: David Landell\n#+EMAIL: david.landell@sunnyhill.email\n#+DATE: 2019\n#+LANGUAGE: en\n#+OPTIONS: bro"
  },
  {
    "path": "docs/utils.org",
    "chars": 2932,
    "preview": "#+MACRO: elisp src_elisp[:results value raw :exports results]{$1}\n#+MACRO: elisp_code src_elisp[:results value :exports "
  },
  {
    "path": "rg-header.el",
    "chars": 6656,
    "preview": ";;; rg-header.el --- Header line for rg-mode -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David Landell <david.lan"
  },
  {
    "path": "rg-history.el",
    "chars": 2238,
    "preview": ";;; rg-history.el --- History navigation in rg.el -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David Landell <davi"
  },
  {
    "path": "rg-ibuffer.el",
    "chars": 3132,
    "preview": ";;; rg-ibuffer.el --- List search buffers for rg-mode -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David Landell <"
  },
  {
    "path": "rg-info-hack.el",
    "chars": 1934,
    "preview": ";;; rg-info-hack.el --- Make sure rg.el info documentation looks good -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2019"
  },
  {
    "path": "rg-isearch.el",
    "chars": 3134,
    "preview": ";;; rg-isearch.el --- rg integration into isearch -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2020 David Landell <davi"
  },
  {
    "path": "rg-menu.el",
    "chars": 9115,
    "preview": ";;; rg-menu.el --- Menu interface for rg -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2017 David Landell <david.landell"
  },
  {
    "path": "rg-result.el",
    "chars": 31135,
    "preview": ";;; rg-result.el ---- Result buffer implementation for rg.el. -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David L"
  },
  {
    "path": "rg.el",
    "chars": 39276,
    "preview": ";;; rg.el --- A search tool based on ripgrep -*- lexical-binding: t; -*-\n\n;; Copyright (C) 1985-1987, 1993-1999, 2001-20"
  },
  {
    "path": "rgel.info",
    "chars": 102290,
    "preview": "This is rgel.info, produced by makeinfo version 7.1 from rgel.texi.\n\n     rg.el 2.4.0, Oct 04, 2025\n\n     David Landell\n"
  },
  {
    "path": "test/data/bar.baz",
    "chars": 18,
    "preview": "hello\nHello\nhellO\n"
  },
  {
    "path": "test/data/bar.el",
    "chars": 18,
    "preview": "hello\nHello\nhellO\n"
  },
  {
    "path": "test/data/context.el",
    "chars": 190,
    "preview": "context1\ncontext2\ncontext3\ncontext4\namid context\ncontext5\ncontext6\ncontext7\ncontext8\namid context\ncontext9\ncontext10\ncon"
  },
  {
    "path": "test/data/dirlocals/.dir-locals.el",
    "chars": 49,
    "preview": "((nil . ((rg-buffer-name . \"from dir locals\"))))\n"
  },
  {
    "path": "test/data/foo.baz",
    "chars": 18,
    "preview": "hello\nHello\nhellO\n"
  },
  {
    "path": "test/data/foo.el",
    "chars": 18,
    "preview": "hello\nHello\nhellO\n"
  },
  {
    "path": "test/data/limenu.el",
    "chars": 6,
    "preview": "imenu\n"
  },
  {
    "path": "test/package-bootstrap.el",
    "chars": 1418,
    "preview": ";;; package-bootstrap.el --- rg.el: Helper for package install test\n\n;; Copyright (C) 2017 David Landell <david.landell@"
  },
  {
    "path": "test/rg-header.el-test.el",
    "chars": 3761,
    "preview": "(require 'cl-lib)\n\n(defvar rg-unit/long-search-pattern \"everything everywhere all at once\")\n\n;;; Mocks.\n\n(cl-defmacro rg"
  },
  {
    "path": "test/rg-history.el-test.el",
    "chars": 3491,
    "preview": ";;; rg-history.el-test.el --- Tests for rg-history.el -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David Landell <"
  },
  {
    "path": "test/rg-isearch.el-test.el",
    "chars": 3574,
    "preview": ";;; rg-isearch.el-test.el --- rg-isearch.el tests -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2020 David Landell <davi"
  },
  {
    "path": "test/rg-menu.el-test.el",
    "chars": 7086,
    "preview": ";;; rg-menu.el-test.el --- Tests for rg-menu.el -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David Landell <david."
  },
  {
    "path": "test/rg.el-test.el",
    "chars": 53462,
    "preview": ";;; rg.el-test.el --- rg.el: Tests -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2017 David Landell <david.landell@sunny"
  },
  {
    "path": "test/style-check.el",
    "chars": 2649,
    "preview": ";;; style-check.el --- rg.el: Check emacs lisp style of package files\n\n;; Copyright (C) 2017 David Landell <david.landel"
  },
  {
    "path": "test/test-helper.el",
    "chars": 7203,
    "preview": ";;; test-helper.el --- rg.el: Helper for tests\n\n;; Copyright (C) 2017 David Landell <david.landell@sunnyhill.email>\n;;\n;"
  },
  {
    "path": "test/wgrep-rg.el-test.el",
    "chars": 6048,
    "preview": ";;; wgrep-rg.el-test.el --- wgrep-rg.el tests -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David Landell <david.la"
  },
  {
    "path": "wgrep-rg.el",
    "chars": 8812,
    "preview": ";;; wgrep-rg.el --- Writable rg buffer and apply the changes to files -*- lexical-binding: t; -*-\n\n;; Author: Masahiro H"
  }
]

About this extraction

This page contains the full source code of the dajva/rg.el GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 45 files (405.9 KB), approximately 103.7k tokens, and a symbol index with 19 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!