[
  {
    "path": ".ert-runner",
    "content": "-L .\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: Build\non:\n  push:\n  release:\n    types:\n      - created\n  pull_request:\n  schedule:\n    - cron: '0 6 1 * *'\njobs:\n  tests:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        emacs_version:\n          - 28.1\n          - 28.2\n          - 29.1\n          - 29.4\n          - 30.1\n          - 30.2\n    steps:\n    - name: Setup emacs-ci-nix for ${{ matrix.emacs_version }}\n      uses: purcell/setup-emacs@master\n      with:\n        version: ${{ matrix.emacs_version }}\n\n    - name: Setup Cask\n      uses: conao3/setup-cask@master\n\n    - name: Checkout repository\n      uses: actions/checkout@v4\n\n    - name: Install ripgrep\n      env:\n        REPO: BurntSushi/ripgrep\n      run: |\n        RELEASE_TAG=$(curl -sL --fail \\\n        -H 'Accept: application/vnd.github.v3+json' \\\n        -H \"Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}\" \\\n        'https://api.github.com/repos/BurntSushi/ripgrep/releases/latest' \\\n        | jq -r '.name')\n\n        PACKAGE_NAME=ripgrep-${RELEASE_TAG}-x86_64-unknown-linux-musl.tar.gz\n\n        curl -sL --fail  \\\n        -H \"Accept: application/vnd.github.v3+json\" \\\n        -H \"Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}\" \\\n        \"https://api.github.com/repos/${REPO}/releases/tags/${RELEASE_TAG}\" \\\n        | jq -r \".assets | .[] | select(.name==\\\"${PACKAGE_NAME}\\\") | .url\" \\\n        | tee asset.url\n\n        curl -sL --fail \\\n        -H \"Accept: application/octet-stream\" \\\n        -H \"Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}\" \\\n        -o \"${PACKAGE_NAME}\" \\\n        \"$(cat asset.url)\"\n        tar xf ${PACKAGE_NAME}\n        echo \"$PWD/$(basename -s .tar.gz $PACKAGE_NAME)\" >> $GITHUB_PATH\n\n    - name: Install emacs deps\n      run: make EMACS_VERSION=${{ matrix.emacs_version }} deps\n\n    - name: Run tests\n      run: |\n        emacs --version\n        rg --version\n        make EMACS_VERSION=${{ matrix.emacs_version }} test\n\n    - name: Coveralls\n      uses: coverallsapp/github-action@master\n      with:\n        github-token: ${{ secrets.GITHUB_TOKEN }}\n        flag-name: emacs-${{ matrix.emacs_version }}\n        parallel: true\n\n  finish:\n    needs: tests\n    runs-on: ubuntu-latest\n    steps:\n    - name: Coveralls Finished\n      uses: coverallsapp/github-action@master\n      with:\n        github-token: ${{ secrets.GITHUB_TOKEN }}\n        parallel-finished: true\n\n"
  },
  {
    "path": ".github/workflows/documentation.yml",
    "content": "name: Documentation\non:\n  push:\n  release:\n    types:\n      - created\njobs:\n  documentation:\n    runs-on: ubuntu-latest\n    steps:\n    - name: Setup emacs-ci-nix for emacs 28.1\n      uses: purcell/setup-emacs@master\n      with:\n        version: 28.1\n\n    - name: Setup Cask\n      uses: conao3/setup-cask@master\n\n    - name: Install sphinx\n      run: sudo apt-get --yes install python3-sphinx\n\n    - name: Checkout repository\n      uses: actions/checkout@v4\n\n    - name: Install emacs deps\n      run: make deps\n\n    - name: Changed files\n      id: files\n      uses: jitterbit/get-changed-files@v1\n      continue-on-error: true\n\n    - name: Extract ref\n      id: extract_ref\n      run: echo ::set-output name=ref::${GITHUB_REF#refs/*/}\n\n    - name: Generate info documentation\n      if:  github.event_name != 'release' && contains(steps.files.outputs.all, 'docs/')\n      run: |\n        make info\n        git config user.name \"GitHub Actions Bot\"\n        git config user.email \"<>\"\n        git add rgel.info\n        git commit -m 'Generate info documentation'\n        git push\n        # Clean to avoid pushing build artifacts in the steps below\n        make clean-docs\n\n    - name: Generate restructured text\n      run:  make rst\n\n    - name: Set documentation branch\n      id: doc_branch\n      run: |\n        if [[ ${{ github.event_name }} = \"release\" ]]; then\n          echo ::set-output name=branch::release\n        else\n          echo ::set-output name=branch::master\n        fi\n\n    - name: Deploy to branch ${{ steps.doc_branch.outputs.branch }}\n      if: github.ref == 'refs/heads/master' || github.event_name == 'release'\n      uses: JamesIves/github-pages-deploy-action@v4.6.4\n      with:\n        branch: ${{ steps.doc_branch.outputs.branch }}\n        folder: docs/rst\n        repository-name: dajva/rg.el-docs\n        token: ${{ secrets.DOCUMENTATION_DEPLOYMENT }}\n\n    - name: Tag release ${{ steps.extract_ref.outputs.ref }}\n      if: github.event_name == 'release'\n      env:\n        RELEASE_VERSION: ${{ steps.extract_ref.outputs.ref }}\n        DOCUMENTATION_DEPLOYMENT: ${{ secrets.DOCUMENTATION_DEPLOYMENT }}\n      run: |\n        git clone https://github.com/dajva/rg.el-docs\n        cd rg.el-docs\n        git checkout release\n        git tag $RELEASE_VERSION\n        git push https://x-access-token:${DOCUMENTATION_DEPLOYMENT}@github.com/dajva/rg.el-docs $RELEASE_VERSION\n"
  },
  {
    "path": ".gitignore",
    "content": ".cask/*\ndist/*\n*.elc\n"
  },
  {
    "path": "Cask",
    "content": "(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 \"rg-ibuffer.el\"\n \"rg-info-hack.el\"\n \"rg-isearch.el\"\n \"rg-menu.el\"\n \"wgrep-rg.el\")\n\n(development\n (depends-on \"cl-lib\" \"0.5\")\n (depends-on \"find-file-in-project\")\n (depends-on \"flycheck\")\n (depends-on \"package-lint\")\n (depends-on \"s\")\n (depends-on \"seq\")\n (depends-on \"transient\")\n (depends-on \"undercover\")\n (depends-on \"wgrep\")\n (depends-on \"ox-rst\" :git \"https://github.com/dajva/ox-rst\"))\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM ubuntu\nSHELL [\"/bin/bash\", \"-c\"]\n\nRUN apt-get -y update\n\n# noninteractive is needed to avoid config of tzlocal package\nRUN DEBIAN_FRONTEND=noninteractive apt-get -y install curl xz-utils make git python3 ripgrep sudo python3-sphinx python3-sphinx-rtd-theme texinfo\n\nRUN install -d -m755 -o $(id ubuntu -u) -g $(id ubuntu -g) /nix\nUSER ubuntu\nENV USER ubuntu\nWORKDIR /home/ubuntu\n\n# Install nix\nRUN curl -L https://nixos.org/nix/install | sh\n\n# Install cachix\nRUN . ~/.nix-profile/etc/profile.d/nix.sh && \\\n    nix-env -iA cachix -f https://cachix.org/api/v1/install\n\n# Install emacs from nix-emacs-ci\nARG EMACS_VERSION=28-2\nRUN . ~/.nix-profile/etc/profile.d/nix.sh && \\\n    cachix use emacs-ci && \\\n    nix-env -iA emacs-${EMACS_VERSION} -f https://github.com/purcell/nix-emacs-ci/archive/master.tar.gz && \\\n    emacs --version\n\n# Install cask\nRUN . ~/.nix-profile/etc/profile.d/nix.sh && \\\n    curl -fsSL https://raw.githubusercontent.com/cask/cask/master/go | python3\n\nENV PATH=/home/ubuntu/.cask/bin:$PATH\nENTRYPOINT [\"bash\", \"-c\", \"source ~/.nix-profile/etc/profile.d/nix.sh && \\\"$@\\\"\", \"-s\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "Makefile",
    "content": "EMACS_VERSION=29-4\nDOCKER_IMAGE=rg.el-test-emacs-$(EMACS_VERSION)\n\nifdef USE_DOCKER\nDOCKER_WRAPPER=docker run --workdir /app --mount type=bind,source=\"$(PWD)\",target=/app $(DOCKER_IMAGE)\n%: run_make\n\t@:\n\n.PHONY: run_make\nrun_make:\n\t$(DOCKER_WRAPPER) $(MAKE) EMACS_VERSION=$(EMACS_VERSION) $(MAKECMDGOALS)\n\nelse  # actual Makefile\n\nPKG_NAME = $(shell cask info | head -1 | cut -f2 -d\" \")\nPKG_VERSION = $(shell cask version)\nPKG_FULL_NAME = $(PKG_NAME)-$(PKG_VERSION)\nSOURCES = $(shell cask files)\nOBJECTS = $(SOURCES:.el=.elc)\nSTYLE_CHECK= -L test -L . -l test/style-check.el\nDISABLE_DEFALIAS_CHECK= --eval \"(defun package-lint--check-defalias (prefix def))\"\n\n# This setup testing similar to ert-runner for legacy reasons.\n# All files under test/ that matches the source files.\nTEST_FILES = $(filter $(patsubst %,test/%-test.el, $(SOURCES)), $(wildcard test/*.el))\n# Load test-helper.el first, then all test files.\nLOAD_TEST_FILES = -L test -l test-helper $(patsubst %,-l %,$(TEST_FILES:test/%.el=%))\n\nSPHINX-BUILD = sphinx-build\nDOC_DIR = docs\nORG_DOCS= $(wildcard $(DOC_DIR)/*.org)\nRST_OUT_DIR = $(DOC_DIR)/rst\nRST_DOCS = $(addprefix $(RST_OUT_DIR)/,$(patsubst %.org,%.rst,$(notdir $(ORG_DOCS))))\n\nall: deps test\n\ndocker-build:\n\tdocker build --build-arg EMACS_VERSION=$(EMACS_VERSION) -t $(DOCKER_IMAGE) .\n\ntest: ert-test style-check package-lint build-test package-test\n\nbuild-test: clean build\n\tcask clean-elc\n\n$(RST_DOCS): | $(RST_OUT_DIR)\n\n$(RST_OUT_DIR):\n\tmkdir $(RST_OUT_DIR)\n\n$(RST_OUT_DIR)/%.rst: docs/%.org\n\tRST_OUT_DIR=$(abspath $(RST_OUT_DIR)) cask emacs --batch -Q -L . -l docs/org-bootstrap.el $< --funcall rg-export-to-rst\n\nrst: $(RST_DOCS)\n\nhtml: rst\n\t$(SPHINX-BUILD) -b html $(RST_OUT_DIR) $(RST_OUT_DIR)/_build/html\n\ninfo: rst\n\t$(SPHINX-BUILD) -b texinfo $(RST_OUT_DIR) $(RST_OUT_DIR)/_build/info\n\tmake -C $(RST_OUT_DIR)/_build/info\n\tcp $(RST_OUT_DIR)/_build/info/rgel.info .\n\ndocs: html\n\nclean-docs:\n\trm $(RST_OUT_DIR)/*.rst\n\tmake -C $(RST_OUT_DIR) clean\n\nclean:\n\tcask clean-elc\n\nbuild: $(OBJECTS)\n\n%.elc: %.el\n\tcask emacs -batch -Q -L . -eval \"(progn (setq byte-compile-error-on-warn t) (batch-byte-compile))\" $<\n\npackage-test:\n\t-@rm -r dist 2> /dev/null || true\n\t-@rm -r /tmp/$(PKG_FULL_NAME)-elpa 2> /dev/null || true\n\tcask package\n\tPKG_FULL_NAME=$(PKG_FULL_NAME) emacs -batch -Q -l test/package-bootstrap.el \\\n\t\t--eval \"(progn (package-install-file (expand-file-name \\\"dist/$(PKG_FULL_NAME).tar\\\")) (rg \\\"rg\\\" \\\"elisp\\\" \\\"/tmp/$(PKG_FULL_NAME)-elpa\\\"))\"\n\nstyle-check:\n\tcask emacs -batch -Q $(STYLE_CHECK) -f run-emacs-lisp-flycheck-and-exit $(SOURCES)\npackage-lint:\n\tcask emacs -batch -Q $(STYLE_CHECK) $(DISABLE_DEFALIAS_CHECK) -f run-package-lint-and-exit rg.el\n\n\nunit-test:\n\tcask emacs --batch -l ert $(LOAD_TEST_FILES) --eval=\"(ert-run-tests-batch-and-exit \\\"rg-unit\\\")\"\n\nintegration-test:\n\tcask emacs --batch -l ert $(LOAD_TEST_FILES) --eval=\"(ert-run-tests-batch-and-exit \\\"rg-integration\\\")\"\n\nert-test:\n\tcask emacs --batch -l ert $(LOAD_TEST_FILES) -f ert-run-tests-batch-and-exit\n\ndeps:\n\tcask install\n\n\n.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\n\nendif\n"
  },
  {
    "path": "README.md",
    "content": "# rg.el\n\n[![License GPL 3](https://img.shields.io/badge/license-GPL_3-green.svg?style=flat)](LICENSE)\n[![MELPA Stable](https://stable.melpa.org/packages/rg-badge.svg)](https://stable.melpa.org/#/rg)\n[![MELPA](http://melpa.org/packages/rg-badge.svg)](http://melpa.org/#/rg)\n[![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)\n[![Coverage Status](https://coveralls.io/repos/github/dajva/rg.el/badge.svg)](https://coveralls.io/github/dajva/rg.el)\n\nUse [ripgrep](https://github.com/BurntSushi/ripgrep) in Emacs.\n\nRipgrep is a replacement for both grep like (search one file) and ag\nlike (search many files) tools. It's fast and versatile and written in\nRust. For some introduction and benchmarks, see\n[ripgrep is faster than {grep, ag, git grep, ucg, pt, sift}](http://blog.burntsushi.net/ripgrep/).\n\n![screenshot](screenshot.png)\n\n## Installation\n\nThis package is available on\n[MELPA Stable](https://stable.melpa.org/#/rg) and\n[MELPA](http://melpa.org/#/rg). Install with `M-x package-install`\n<kbd>RET</kbd> `rg` from within Emacs.\n\nIt is also available in GNU Guix as\n[emacs-rg](https://guix.gnu.org/en/packages/emacs-rg-2.2.0/).  Install\nwith `guix package -i emacs-rg`.\n\nIf you want to install manually just put `rg.el` and the rest of the\nelisp files somewhere in your load path and add require the package:\n\n``` el\n(require 'rg)\n```\n\n`rg` and friends are autoloaded symbols which means it's also possible\nto defer loading if you have autoloading setup.\n\n### Setup key bindings\nThis will setup the default key bindings in a non lazy way. If you\ncare about startup performance see the next example.\n\n``` el\n(rg-enable-default-bindings)\n```\n\nSee\n[documentation](https://rgel.readthedocs.io) for how to handle lazy loading.\n\n\n### Use old defaults\n`rg.el` 2.0.0 will use new default settings to improve look and feel,\nmore consistent key bindings etc. If you want to use the old defaults\nadd this to your `init.el`:\n\n``` el\n(rg-use-old-defaults)\n```\n\n### rg-menu\n\nIf you prefer to use a [magit](https://github.com/magit/magit) like\ninterface as a complement to regular key maps, replace\n`(rg-enable-default-bindings)` with `(rg-enable-menu)`. The menus are\nbuilt with [transient](https://github.com/magit/transient), which\nmeans that the menus can be modified in the same way as in magit.\n\n## Documentation\nInfo documentation is included in the package.\nOnline documentation: https://rgel.readthedocs.io\n\n## Contribute\n\n- Install [cask](http://cask.github.io/).\n- Install dependencies:\n\n``` Shell\nmake deps\n```\n- Run tests:\n\n``` Shell\nmake test\n```\n\n\n## License\n\nSee [LICENSE](LICENSE).\n"
  },
  {
    "path": "docs/configuration.org",
    "content": "#+TITLE: Configuration\n#+AUTHOR: David Landell\n#+EMAIL: david.landell@sunnyhill.email\n#+DATE: 2019\n#+LANGUAGE: en\n#+OPTIONS: broken-links:auto, toc:nil, email:nil, num:nil, ^:nil, author:nil, date:nil\n\n#+INCLUDE: \"utils.org\"\n\n* Customization\n  :PROPERTIES:\n  :CUSTOM_ID: customization\n  :END:\n  Customization is done via the Emacs customization system. The group\n  =rg= is the main group of the package.\n  #+BEGIN_SRC elisp\n  M-x customize-group [RET] rg [RET]\n  #+END_SRC\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-executable '(executable-find \"rg\"))\n  #+END_SRC\n\n  The /ripgrep/ executable to use. Could be an absolute path or just the\n  base name if the executable is in the path. The default is using\n  =executable-find= to locate the command. If you want to use this\n  package with tramp it might be better to set it to just \"rg\" in\n  order to let the OS find the binary where it's invoked.\n  From Emacs 27.1, the tramp use case is by default handled\n  automatically. See [[opt:rg-executable-per-connection]] for details.\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-executable-per-connection)\n  #+END_SRC\n\n  This setting only has effect in Emacs 27.1 or later.\n  Handle the [[opt:rg-executable]] automatically for different hosts if used\n  with tramp. =executable-find= for \"rg\" binary will be invoked on\n  remote hosts to determine the path to ripgrep. The result is stored\n  per connection.\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-custom-type-aliases)\n  #+END_SRC\n\n  An association list that maps file type aliases to a space\n  delimited string with file globs. These are combined with the\n  /ripgrep/ builtin file aliases.\n\n  Example:\n  #+BEGIN_SRC elisp\n    (setq rg-custom-type-aliases\n      '((\"foo\" .    \"*.foo *.bar\")\n        (\"baz\" .    \"*.baz *.qux\")))\n  #+END_SRC\n\n  You may also add lambdas to =rg-custom-type-aliases= to add aliases\n  dynamically based on mode, directory, project, etc.\n\n  #+BEGIN_SRC elisp\n     (add-to-list\n      'rg-custom-type-aliases\n      (lambda ()\n        (when (in-frontend-app)\n          (cons \"ui\" \"*.js *.hbs *.json\"))))\n  #+END_SRC\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-prioritized-type-aliases)\n  #+END_SRC\n\n  A list of aliases that are prioritized among ripgrep's builtin\n  aliases when selecting the alias based on the buffer file name. This\n  list contains only the alias names and the order between the items\n  does not matter.\n\n  Example:\n  #+BEGIN_SRC elisp\n    (setq rg-custom-type-aliases\n      '(\"cpp\" \"puppet\"))\n  #+END_SRC\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-default-alias-fallback)\n  #+END_SRC\n\n  This setting controls the default alias used when no alias can be\n  recognized for the current buffer. =all= or =everything= are\n  reasonable values for this variable.\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-command-line-flags)\n  #+END_SRC\n\n  A list of command line flags that will be appended to the\n  /ripgrep/ command line. Must either be a list of flags or a function\n  that returns a list of flags.\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-group-result)\n  #+END_SRC\n\n\n  Controls the layout of the results buffer. If non =nil=, each file name\n  is displayed once and matches are grouped under that filename instead of\n  repeating the filename on each match. This is essentially the layout of\n  the =--no-heading= /ripgrep/ command line flag.\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-show-columns)\n  #+END_SRC\n\n\n  Controls if column numbers are used in the search result.\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-ignore-case)\n  #+END_SRC\n\n  Setting that controls if case sensitive search is made or not. It\n  can essentially be *on*, *off* or *smart*. The *smart* setting will\n  trigger an analyze of the search string and if it's all lower case,\n  the search will be case /insensitive/, otherwise it will be case\n  /sensitive/. The following values are valid:\n\n  - *case-fold-search* - A non nil value of =case-fold-search= will trigger smart case behavior.\n  - *smart* - Smart case behavior.\n  - *force* - Always ignore case.\n  - *nil* - Always consider case.\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-hide-command)\n  #+END_SRC\n\n  Hide most of command line by default. This is enabled by default and can\n  be set to =nil= to show full command line.\n  This can be toggled in the results buffer by clicking on the command line.\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-keymap-prefix)\n  #+END_SRC\n\n  This variable sets the default prefix used for the global key bindings.\n  Note that =rg-enable-default-bindings= needs to be invoked for the\n  bindings to be enabled.\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-use-transient-menu)\n  #+END_SRC\n\n  Controls whether =rg-menu= will be used by default or not. It's also\n  possible to enable the menu explicitly with\n  #+BEGIN_SRC elisp\n  (rg-enable-menu)\n  #+END_SRC\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-show-header)\n  #+END_SRC\n\n  Controls if the search info header is shown in the result buffer. This\n  is enabled by default but can be disabled by setting this variable to\n  =nil=.\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-buffer-name)\n  #+END_SRC\n\n  Controls the name of the results buffer. It may be /string/ or /function/.\n  This name will be surrounded by  =*= to yield the final buffer name\n  so if this setting is =foo= the buffer name will be =*foo*=.\n  One useful case of using it is to have separate result buffers per project.\n  One can set this variable in `dir-locals` file or set it to function.\n\n  Example, this function will set results buffer name based on `project-current`:\n  #+BEGIN_SRC elisp\n    (defun my-rg-buffer-name ()\n      (let ((p (project-current)))\n        (if p\n            (format \"rg %s\" (abbreviate-file-name (cdr p)))\n          \"rg\")))\n  #+END_SRC\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-ignore-ripgreprc)\n  #+END_SRC\n\n  Controls if the [[https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md#configuration-file][ripgreprc]] file should be ignored or not. If =nil=,\n  the config file will be used, otherwise it will be ignored. The\n  default is to ignore this file in order to avoid that conflicting\n  settings have impact on this package's behavior. Setting this to =nil=\n  may affect core functionality of this package. Especially changing\n  colors can affect parsing of the output and result in a broken\n  results buffer.\n  :END:\n\n*** Position numbers alignment\n    :PROPERTIES:\n    :CUSTOM_ID: position-numbers-alignment\n    :END:\n\n    When operating /rg/ in grouped output mode ([[opt:rg-group-result]] is non\n    nil), it's possible to control how the line and column numbers are\n    displayed in the result buffer.\n\n    Example settings:\n\n    #+BEGIN_SRC elisp\n    (setq rg-align-position-numbers t)\n    (setq rg-align-line-number-field-length 3)\n    (setq rg-align-column-number-field-length 3)\n    (setq rg-align-line-column-separator \"#\")\n    (setq rg-align-position-content-separator \"|\")\n    #+END_SRC\n\n    Will yield the following format:\n\n    #+BEGIN_EXAMPLE\n    File: matched_file.foo\n      1#  2|match1\n    888# 10|match2\n    #+END_EXAMPLE\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-custom-info 'rg-align-position-numbers)\n    #+END_SRC\n\n    Setting this to =t= will align line and column numbers in columns padded\n    with white space.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-custom-info 'rg-align-line-number-field-length)\n    #+END_SRC\n\n\n    Defines the length of the line number field.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-custom-info 'rg-align-column-number-field-length)\n    #+END_SRC\n\n\n    Defines the length of the column number field.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-custom-info 'rg-align-line-column-separator)\n    #+END_SRC\n\n\n    Separator string used between line and column numbers. =nil= means\n    use default separator from /ripgrep/.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-custom-info 'rg-align-position-content-separator)\n    #+END_SRC\n\n    Separator string used between the position numbers and matched content. =nil= means\n    use default separator from /ripgrep/.\n    :END:\n\n* Faces\n  All faces are in the subgroup =rg-face= of the main group =rg=.\n  #+BEGIN_SRC elisp\n  M-x customize-group [RET] rg-face [RET]\n  #+END_SRC\n*** Results buffer\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-face-info 'rg-match-face)\n    #+END_SRC\n    Face used to highlight matches in result.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-face-info 'rg-error-face)\n    #+END_SRC\n    Face used to highlight errors when invoking /ripgrep/.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-face-info 'rg-context-face)\n    #+END_SRC\n    Face used to highlight context lines in /ripgrep/ output when\n    =--context-lines= flag is used.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-face-info 'rg-info-face)\n    #+END_SRC\n    Face used to highlight general info in results buffer. For instance\n    the number of matches found.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-face-info 'rg-warning-face)\n    #+END_SRC\n    Face used to highlight warnings in the /ripgrep/ output.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-face-info 'rg-filename-face)\n    #+END_SRC\n    Face used to highlight filenames in the output.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-face-info 'rg-file-tag-face)\n    #+END_SRC\n    Face used for the =File:= tag in grouped results output.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-face-info 'rg-line-number-face)\n    #+END_SRC\n    Face used on line numbers.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-face-info 'rg-column-number-face)\n    #+END_SRC\n    Face used on column numbers.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-face-info 'rg-match-position-face)\n    #+END_SRC\n    Face added to file positions. This is the start of a matching line\n    and depending on configuration may be, file name, column number and\n    line number.\n    :END:\n\n\n*** Header line\n    :PROPERTIES:\n    :CUSTOM_ID: header_line_config\n    :END:\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-face-info 'rg-toggle-on-face)\n    #+END_SRC\n    Face used for flags that are toggled =on=.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n   (rg-face-info 'rg-toggle-off-face)\n    #+END_SRC\n    Face used for flags that are toggled =off=.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-face-info 'rg-literal-face)\n    #+END_SRC\n    Face used the on the =literal= marker in the header line.\n    :END:\n\n    :OPTION:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-face-info 'rg-regexp-face)\n    #+END_SRC\n    Face used the on the =regexp= marker in the header line.\n    :END:\n\n* Configuration functions\n  :PROPERTIES:\n  :CUSTOM_ID: configuration_functions\n  :END:\n\n  :FUNCTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-function-info 'rg-enable-default-bindings)\n  #+END_SRC\n  Enable the default keyboard bindings for the package with prefix\n  key. If [[opt:rg-use-transient-menu]] is on this will enable the menu\n  instead of activating the global bindings. If =prefix= is not\n  provided [[opt:rg-keymap-prefix]] will be used.\n  :END:\n\n  :FUNCTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-function-info 'rg-enable-menu)\n  #+END_SRC\n  Enable the [[file:usage.org::#the_menu][rg-menu]] with prefix key. This bypass\n  [[opt:rg-use-transient-menu]] setting. If =prefix= is not provided\n  [[opt:rg-keymap-prefix]] will be used.\n  :END:\n\n  :FUNCTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-function-info 'rg-use-old-defaults)\n  #+END_SRC\n  This function is provided to keep backwards compatibility with\n  versions older than 2.0.0. In this version default settings as well\n  as key bindings changed and to bring back the old defaults call this\n  function in your init file.\n  :END:\n\n* Hooks\n  :PROPERTIES:\n  :CUSTOM_ID: hooks\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-finish-functions)\n  #+END_SRC\n  Functions to call when a ripgrep search is finished.\n\n  Each function is called with two arguments: the compilation buffer,\n  and a string describing how the process finished.\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-filter-hook)\n  #+END_SRC\n  Hook run after new content has been inserted in in the rg buffer.\n  This hook is called every time the rg buffer has been updated with\n  new content and filtered internally by the package.\n  :END:\n\n  :OPTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-custom-info 'rg-mode-hook)\n  #+END_SRC\n  Hook run after entering rg mode.\n  :END:\n\n* Configuration macros\n  :PROPERTIES:\n  :CUSTOM_ID: configuration_macros\n  :END:\n\n  :FUNCTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-function-info 'rg-define-toggle)\n  #+END_SRC\n\n  This is a macro that can be used to define custom /ripgrep/ flag\n  toggling functions in the result buffer. The macro takes the flag\n  (and potential value) as an argument and optionally binds the toggle\n  function to a key. If =default= is non nil the flag is used by default.\n\n  The function defined by this macro will be named as the flag name\n  stripped with leading dashes and prefixed with =rg-custom-toggle-flag-=.\n\n  #+BEGIN_SRC elisp\n    (rg-define-toggle \"-uu\" \"I\" t)\n  #+END_SRC\n\n  Creates a function named =rg-custom-toggle-flag-uu= that is on by\n  default and bound to =I= in /rg/ result\n  buffer.\n\n  #+BEGIN_SRC elisp\n    (rg-define-toggle \"--context 3\" (kbd \"C-c c\"))\n  #+END_SRC\n\n  Creates a function named =rg-custom-toggle-flag-context= that is off by\n  default and bound to =C-c c= in /rg/ result\n  buffer.\n  :END:\n\n  :FUNCTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-function-info 'rg-define-search)\n  #+END_SRC\n\n  This macro can be used to define custom search functions in a\n  declarative style. Default implementations for common behavior is\n  available and custom forms can also be used.\n\n  It optionally starts with a string that is used as the docstring for\n  the defined function.  The rest of the arguments contain key value pairs\n  according to the specification below.  All keys are optional with\n  specified default if left out.\n\n  - *:query* - Method for retrieving the search string.  Allowed values are\n    =point= which means extract thing at point and =ask= which means\n    prompt the user for a string.  Any form that evaluates to a string\n    is allowed. Default is =ask=.\n  - *:format* - Specifies if =:query= is interpreted literally\n    (=literal=) or as a regexp (=regexp=). If it is a form, eg.\n    =(not current-prefix-arg)=, and is non-nil the =:query= is interpreted\n    literally, otherwise as a regexp. Default is =regexp=.\n  - *:files* - Form that evaluates to a file alias or custom file\n    glob. =current= means extract alias from current buffer file name,\n    =ask= will prompt the user. Default is =ask=.\n  - *:dir* - Root search directory.  Allowed values are =ask= for user\n    prompt, =current= for current dir and =project= for project\n    root.  Any form that evaluates to a directory string is also allowed.\n    Default is =ask=.\n  - *:confirm* - =never=, =always=, or =prefix= are allowed values.  Specifies\n    if the the final search command line string can be modified\n    and confirmed the user. Default is =never=.\n  - *:flags* - =ask= or a list of command line flags that will be used when\n    invoking the search.\n  - *:menu* - Bind the command into =rg-menu=.  Must be a list with three\n    items in it.  The first item is the description of the\n    group in which the new command will appear.  If the group\n    does not exist a new will be created.  The second item is\n    the key binding for this new command (ether a key vector\n    or a key description string) and the third item is the\n    description of the command that will appear in the menu.\n\n  Examples:\n  #+BEGIN_SRC elisp\n    (rg-define-search search-everything-at-home\n      \"Search files including hidden in home directory\"\n      :query ask\n      :format literal\n      :files \"everything\"\n      :flags (\"--hidden\")\n      :dir (getenv \"HOME\")\n      :menu (\"Search\" \"h\" \"Home\"))\n\n    (rg-define-search rg-emacs\n      \"Search the emacs lisp source code.\"\n      :dir \"/usr/share/emacs/25.2/lisp/\"\n      :flags '(\"-z\")\n      :files \"*.{el,el.gz}\"\n      :menu (\"Custom\" \"L\" \"lisp\"))\n  #+END_SRC\n  :END:\n\n* Use with evil-mode\n  Some key bindings clash with /evil-mode/. Recommendation is to use\n  evil /motion/ state for the results buffer and then switch to\n  evil /normal/ mode when editing in /wgrep-mode/. Some adjustments\n  need to be done to avoid the clashes though.\n\n  This is a start of a configuration. This let /rg-mode/'s key bindings\n  override the motion state map bindings based on that these motion\n  keys are not important in an /rg/ results buffer.\n  Adjust this to your preferred use case:\n  #+begin_src elisp\n    (with-eval-after-load 'rg\n      (advice-add 'wgrep-change-to-wgrep-mode :after\n                  #'evil-normal-state)\n      (advice-add 'wgrep-to-original-mode :after\n                  #'evil-motion-state)\n      (defvar rg-mode-map)\n      (add-to-list 'evil-motion-state-modes 'rg-mode)\n      (evil-add-hjkl-bindings rg-mode-map 'motion\n        \"e\" #'wgrep-change-to-wgrep-mode\n        \"g\" #'rg-recompile\n        \"t\" #'rg-rerun-change-literal))\n  #+end_src\n\n* Customizing the menu\n  :PROPERTIES:\n  :CUSTOM_ID: customizing_the_menu\n  :END:\n  The menu can be modified from the emacs configuration file.\n\n  To add a new *switch* before the option triggered by =-n= at suffix\n  level 3:\n  #+BEGIN_SRC elisp\n    (transient-insert-suffix 'rg-menu \"-n\" '(3 \"-o\" \"Only print matches\" \"--only-matching\"))\n  #+END_SRC\n  To add a new *option* before the option triggered by =-g= at suffix\n  level 4:\n  #+BEGIN_SRC elisp\n    (transient-insert-suffix 'rg-menu \"-g\" '(4 \"-f\" \"Pattern file\" \"--file=\"))\n  #+END_SRC\n  The === in =--file== triggers argument input for the flag.\n\n  To remove an item from the menu specify the trigger key in the\n  transient remove command.\n  For example, to remove the =Search hidden files= switch use the following:\n  #+BEGIN_SRC elisp\n    (transient-remove-suffix 'rg-menu \"-h\")\n  #+END_SRC\n\n  Please refer to the [[https://magit.vc/manual/transient/Modifying-Existing-Transients.html#Modifying-Existing-Transients][transient]] documentation for details on customizing the menu.\n\n  This package also adds a convenience function for appending new\n  *commands* to the menu in the groups at the bottom.\n\n  :FUNCTION:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-function-info 'rg-menu-transient-insert)\n  #+END_SRC\n  This inserts a new command under =group= if it exists, otherwise a\n  new group is created. =key=, =description= and =command= is as for\n  the =transient-insert-suffix= function.\n\n  For example to insert a new command under =Search= group:\n  #+BEGIN_SRC elisp\n    (rg-menu-transient-insert \"Search\" \"m\" \"My search\" 'my-search-command)\n  #+END_SRC\n\n  It's usually better to use the =:menu= key of the [[func:rg-define-search]]\n  macro to define a search function and adding it to the menu in one go.\n  :END:\n\n"
  },
  {
    "path": "docs/contribute.org",
    "content": "#+TITLE: Contribute\n#+AUTHOR: David Landell\n#+EMAIL: david.landell@sunnyhill.email\n#+DATE: 2019\n#+LANGUAGE: en\n#+OPTIONS: broken-links:auto, toc:nil, email:nil, num:nil, ^:nil, author:nil, date:nil\n\n#+INCLUDE: \"utils.org\"\n\nContributions are very welcome. Development is done in the [[https://github.com/dajva/rg.el][GitHub\nrepository]]. If you find a bug, please report it in the [[https://github.com/dajva/rg.el/issues][issue tracker]].\n\n\n* Pull requests\n  :PROPERTIES:\n  :CUSTOM_ID: pull_requests\n  :END:\n  If you want to submit a patch, please submit a [[https://github.com/dajva/rg.el/pulls][GitHub pull\n  request]]. If you want to submit any larger code changes, please create an\n  issue first for discussion. Some features does not fit well into\n  this package and there is also good to agree on the general design\n  before doing any major work.\n\n  The minimum requirements for a pull request to be accepted is that\n  all existing tests pass and test coverage should not decrease. Often\n  a patch also needs additional tests, new/changed documentation etc.\n\n  Don't strive to submit a perfect pull request directly. It's often\n  better to submit something simple that shows the main direction of\n  the new code in order to discuss the best way to proceed and what\n  additions are needed.\n\n* Docker\n  :PROPERTIES:\n  :CUSTOM_ID: docker\n  :END:\n  Docker can be used to run the tests or generate documentation\n  locally without installing dependencies on the host and to test with\n  different emacs versions.\n\n  To use docker, just set the =USE_DOCKER= variable when\n  running the tests.\n  The =EMACS_VERSION= variable can be used to select emacs\n  version. Note that dash ('-') is used instead of points ('.') in the\n  version numbering. So emacs 28.2 is specified as =28-2=.\n  Emacs are installed from https://github.com/purcell/nix-emacs-ci so\n  only emacs versions supported in that repository will work.\n  - Build docker container:\n    #+begin_src bash\n      # Don't use the USE_DOCKER variable here\n      make EMACS_VERSION=30-2 docker-build\n    #+end_src\n  - To run all the tests in docker image:\n    #+begin_src bash\n     make USE_DOCKER=true test\n    #+end_src\n  - Use a specific emacs version:\n    #+begin_src bash\n      make USE_DOCKER=true EMACS_VERSION=snapshot\n    #+end_src\n  - Generate html documentation:\n    #+begin_src bash\n      make USE_DOCKER=true html\n    #+end_src\n\n* Tests\n  :PROPERTIES:\n  :CUSTOM_ID: tests\n  :END:\n  [[https://cask.readthedocs.io/][Cask]] is used for testing. The tests are written using the Emacs\n  built in ERT framework and follows the conventions of [[https://github.com/rejeep/ert-runner.el][ert runner]]\n  although ert_runner is no longer used. There are also compilation\n  tests, style check, package verification etc.\n*** Setup\n    :PROPERTIES:\n    :CUSTOM_ID: tests_setup\n    :END:\n    - [[https://cask.readthedocs.io/en/latest/guide/installation.html][Install cask]]\n    - Install all developer dependencies:\n      #+BEGIN_SRC bash\n      make deps\n      #+END_SRC\n*** Running\n    :PROPERTIES:\n    :CUSTOM_ID: tests_running\n    :END:\n    - Run the whole test suite:\n      #+BEGIN_SRC bash\n      make test\n      #+END_SRC\n    - Run only the unit/integration tests:\n      #+BEGIN_SRC bash\n      make ert-test\n      #+END_SRC\n    - Manually test the package with Emacs:\n      #+BEGIN_SRC bash\n      cask emacs -Q -L . --eval=\"(progn (require 'rg) (enable-default-bindings))\"\n      #+END_SRC\n\n\n* Documentation\n  :PROPERTIES:\n  :CUSTOM_ID: documentation\n  :END:\n  The documentation is written in org mode. The export target is\n  [[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\n  generator. Sphinx is used to export the output from org mode to info\n  and HTML documentation. The resulting .rst files are used for the online\n  documentation on [[https://readthedocs.io]].\n\n  The end user documentation is generated after committing to the\n  main repository. It's advisable to build\n  both html and info documentation locally and verify the output to\n  make sure the changes looks as expected.\n*** Setup\n    :PROPERTIES:\n    :CUSTOM_ID: documentation_setup\n    :END:\n    - [[http://www.sphinx-doc.org/en/master/usage/installation.html][Install Sphinx]]\n      #+BEGIN_SRC bash\n      sudo apt install python3-sphinx python3-sphinx-rtd-theme\n      #+END_SRC\n    - Install makeinfo\n      #+begin_src bash\n      sudo apt install texinfo\n      #+end_src\n*** Building\n    :PROPERTIES:\n    :CUSTOM_ID: documentation_building\n    :END:\n    - HTML documentation\n      #+BEGIN_SRC bash\n      make html\n      #+END_SRC\n      Open =docs/rst/_build/html/index.html= in a browser.\n    - Info documentation\n      #+BEGIN_SRC bash\n      make info\n      #+END_SRC\n      To view in emacs:\n      #+BEGIN_SRC elisp\n      C-u M-x info [RET]\n      #+END_SRC\n      Then select the =docs/rst/_build/info/rgel.info= file.\n"
  },
  {
    "path": "docs/gpl.org",
    "content": "#+TITLE: GNU General Public License\n#+AUTHOR: David Landell\n#+EMAIL: david.landell@sunnyhill.email\n#+DATE: 2019\n#+LANGUAGE: en\n#+OPTIONS: broken-links:auto, toc:nil, email:nil, num:nil, ^:nil, author:nil, date:nil\n\n\n#+BEGIN_EXPORT rst\n.. _gpl:\n#+END_EXPORT\n\n#+INCLUDE: \"../LICENSE\" example\n"
  },
  {
    "path": "docs/index.org",
    "content": "#+TITLE: Rg Manual\n#+AUTHOR: David Landell\n#+EMAIL: david.landell@sunnyhill.email\n#+DATE: 2019\n#+LANGUAGE: en\n#+OPTIONS: broken-links:auto, toc:nil, email:nil, num:nil, ^:nil, author:nil, date:nil\n\n/rg.el/ is an Emacs search package based on the [[https://github.com/BurntSushi/ripgrep][ripgrep]] command line\ntool. It allows you to interactively create searches, doing automatic\nsearches based on the editing context, refining and modifying search\nresults and much more. It is also highly configurable to be able to\nfit different users' needs.\n\nThroughout this manual this emacs package will be referred to as /rg/\nwhile the command line utility will be referred to as /ripgrep/.\n\nIf you are used to built-in Emacs =rgrep= command, transitioning to\n/rg/ should be simple. /rg/ provides a lot of extra features\nbut the basics are similar.\n\nThe big benefit of using /ripgrep/ instead of /grep/ as a backend is\nspeed. Especially when searching large source code repositories\nwhere /ripgrep/ really shines. Please read [[http://blog.burntsushi.net/ripgrep/][this blog post]] for some\nspeed comparisons with other tools.\n\n#+BEGIN_EXPORT rst\n.. toctree::\n   :maxdepth: 2\n\n   usage\n   configuration\n   contribute\n#+END_EXPORT\n\n* License\n  :PROPERTIES:\n  :CUSTOM_ID: license\n  :END:\n  /rg/ is free software; you can redistribute it and/or\n  modify it under the terms of the GNU General Public License\n  as published by the Free Software Foundation; either version 3\n  of the License, or (at your option) any later version.\n\n  /rg/ is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  [[file:gpl.org::#gpl][GNU General Public License]] for more details.\n\n#+BEGIN_EXPORT rst\n.. toctree::\n   :maxdepth: 2\n\n   gpl\n#+END_EXPORT\n"
  },
  {
    "path": "docs/org-bootstrap.el",
    "content": ";;; org-bootstrap.el --- Description -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2019 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;;; Code:\n\n(require 'ox-rst)\n(require 'package)\n(require 'rg)\n\n;; General org mode settings\n\n(setq org-odd-levels-only t)\n(setq org-confirm-babel-evaluate nil)\n\n;; org ox-rst settings\n(setq org-rst-pygments-langs\n      '((lisp \"common-lisp\")\n        (cc \"c++\")\n        (cperl \"perl\")\n        (latex \"tex\")\n        (shell-script \"bash\")\n        (caml \"ocaml\")\n        (sqlite3 \"sqlite\")))\n\n(setq org-rst-code-block 'code-block)\n(setq org-rst-link-use-ref-role t)\n(setq org-rst-file-link-use-ref-role t)\n\n(defun rg-format-todo (todo todo-type priority title tags contents)\n  (when (eq todo-type 'todo)\n    (let* ((padding \"   \")\n           (formated-contents\n            (when contents\n              (concat padding\n                      (mapconcat 'identity (split-string contents \"\\n\")\n                                 (concat \"\\n\" padding))))))\n      (concat (format (concat \".. todo:: %s\\n\\n\") title)\n              formated-contents \"\\n\"))))\n(setq org-rst-format-inlinetask-function #'rg-format-todo)\n\n(defun rg-format-drawer (name contents info)\n  (let* ((lines (split-string contents \"\\n\"))\n         (heading (car lines))\n         (body (cdr lines)))\n    (format \".. %s:: %s\\n%s\\n\\n\"\n            (downcase name)\n            heading\n            (concat \"   \" (mapconcat #'identity body (concat \"\\n\" \"   \"))))))\n(setq org-rst-format-drawer-function #'rg-format-drawer)\n\n(defun rg-func-role-link (path desc backend)\n  (rg-ref-role-link \"func\" path desc backend))\n\n(defun rg-cmd-role-link (path desc backend)\n  (rg-ref-role-link \"cmd\" path desc backend))\n\n(defun rg-opt-role-link (path desc backend)\n  (rg-ref-role-link \"opt\" path desc backend))\n\n(defun rg-var-role-link (path desc backend)\n  (rg-ref-role-link \"var\" path desc backend))\n\n(defun rg-ref-role-link (role path desc backend)\n  (when (eq backend 'rst)\n    (if desc\n        (format \":%s:`%s <%s>`\" role desc path)\n      (format \":%s:`%s`\" role path))))\n\n(push '(\"func\" :export rg-func-role-link ) org-link-parameters)\n(push '(\"cmd\" :export rg-cmd-role-link ) org-link-parameters)\n(push '(\"opt\" :export rg-opt-role-link ) org-link-parameters)\n(push '(\"var\" :export rg-var-role-link ) org-link-parameters)\n\n(add-to-list 'load-path nil)\n\n(defvar rst-out-dir (getenv \"RST_OUT_DIR\"))\n\n(defun rg-export-to-rst ()\n  (interactive)\n  (let ((outfile (org-export-output-file-name \".rst\" nil rst-out-dir)))\n    (org-export-to-file 'rst outfile)))\n\n(provide 'org-bootstrap)\n\n;;; org-bootstrap.el ends here\n"
  },
  {
    "path": "docs/rst/Makefile",
    "content": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nSOURCEDIR     = .\nBUILDDIR      = _build\n\n# Put it first so that \"make\" without argument is like \"make help\".\nhelp:\n\t@$(SPHINXBUILD) -M help \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n\n.PHONY: help Makefile\n\n# Catch-all target: route all unknown targets to Sphinx using the new\n# \"make mode\" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).\n%: Makefile\n\t@$(SPHINXBUILD) -M $@ \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)"
  },
  {
    "path": "docs/rst/conf.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# Configuration file for the Sphinx documentation builder.\n#\n# This file does only contain a selection of the most common options. For a\n# full list see the documentation:\n# http://www.sphinx-doc.org/en/master/config\n\n# -- Path setup --------------------------------------------------------------\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#\nimport os\nimport sys\nsys.path.insert(0, os.path.abspath('.'))\n\n# -- Project information -----------------------------------------------------\n\nproject = u'rg.el'\ncopyright = u'2019, David Landell'\nauthor = u'David Landell'\n\n# The short X.Y version\nversion = u''\n# The full version, including alpha/beta/rc tags\nrelease = u'2.4.0'\n\n# -- General configuration ---------------------------------------------------\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#\n# needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = [\n    'sphinx.ext.todo',\n    'elispdomain'\n]\n\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n#\nsource_suffix = ['.rst']\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = 'en'\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\n# This pattern also affects html_static_path and html_extra_path.\nexclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store', 'README.rst']\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = None\n\n\n# -- Options for HTML output -------------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\n#\n# html_theme = 'alabaster'\nhtml_theme = 'sphinx_rtd_theme'\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#\n# html_theme_options = {}\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\n\n# Custom sidebar templates, must be a dictionary that maps document names\n# to template names.\n#\n# The default sidebars (for documents that don't match any pattern) are\n# defined by theme itself.  Builtin themes are using these templates by\n# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',\n# 'searchbox.html']``.\n#\n# html_sidebars = {}\n\n\n# -- Options for HTMLHelp output ---------------------------------------------\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'rgeldoc'\n\n\n# -- Options for LaTeX output ------------------------------------------------\n\nlatex_elements = {\n    # The paper size ('letterpaper' or 'a4paper').\n    #\n    # 'papersize': 'letterpaper',\n\n    # The font size ('10pt', '11pt' or '12pt').\n    #\n    # 'pointsize': '10pt',\n\n    # Additional stuff for the LaTeX preamble.\n    #\n    # 'preamble': '',\n\n    # Latex figure (float) alignment\n    #\n    # 'figure_align': 'htbp',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n    (master_doc, 'rgel.tex', u'rg.el Documentation',\n     u'David Landell', 'manual'),\n]\n\n\n# -- Options for manual page output ------------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    (master_doc, 'rgel', u'rg.el Documentation',\n     [author], 1)\n]\n\n\n# -- Options for Texinfo output ----------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n    (master_doc, 'rgel', u'RG User Manual',\n     author, 'RG', 'Search like a King with ripgrep in Emacs.',\n     'Emacs'),\n]\n\ntexinfo_elements = {'preamble': \"\"\"\n@definfoenclose strong,*,*\n@definfoenclose emph,_,_\n\"\"\"}\n\ntexinfo_show_urls='inline'\ntexinfo_no_detailmenu=True\n\n# -- Options for Epub output -------------------------------------------------\n\n# Bibliographic Dublin Core info.\nepub_title = project\n\n# The unique identifier of the text. This can be a ISBN number\n# or the project homepage.\n#\n# epub_identifier = ''\n\n# A unique identification for the text.\n#\n# epub_uid = ''\n\n# A list of files that should not be packed into the epub file.\nepub_exclude_files = ['search.html']\n\n\n# -- Extension configuration -------------------------------------------------\n\n# -- Options for todo extension ----------------------------------------------\n\n# If true, `todo` and `todoList` produce output, else they produce nothing.\ntodo_include_todos = True\n\nadd_function_parentheses=False\n"
  },
  {
    "path": "docs/rst/elispdomain.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nEmacs Lisp Domain for Sphinx\n\nCopyright 2014 by Jorgen Schäfer\n\n\"\"\"\n\nfrom sphinx import addnodes\nfrom sphinx.domains import Domain, ObjType\nfrom sphinx.locale import _\nfrom sphinx.directives import ObjectDescription\nfrom sphinx.roles import XRefRole\nfrom sphinx.util.nodes import make_refnode\n\n\nclass ELispMarkup(ObjectDescription):\n    def add_target_and_index(self, name, sig, signode):\n        targetname = self.objtype + '-' + name\n        if targetname not in self.state.document.ids:\n            signode['names'].append(targetname)\n            signode['ids'].append(targetname)\n            signode['first'] = (not self.names)\n            self.state.document.note_explicit_target(signode)\n\n            objects = self.env.domaindata['el']['objects']\n            key = (self.objtype, name)\n            if key in objects:\n                self.state_machine.reporter.warning(\n                    'duplicate description of %s %s, ' % (self.objtype, name) +\n                    'other instance in ' + self.env.doc2path(objects[key]),\n                    line=self.lineno)\n            objects[key] = self.env.docname\n        indextext = self.get_index_text(self.objtype, name)\n        if indextext:\n            self.indexnode['entries'].append(('single', indextext,\n                                              targetname, '', None))\n\n\nclass ELispFunction(ELispMarkup):\n    def get_index_text(self, objectname, name):\n        return \"{} (function)\".format(name)\n\n    def handle_signature(self, sig, signode):\n        if sig.startswith(\"(\"):\n            sig = sig[1:]\n        if sig.endswith(\")\"):\n            sig = sig[:-1]\n        name, args = sig.split(\" \", 1)\n\n        params = addnodes.desc_parameterlist()\n        if args:\n            params += addnodes.desc_name(name, name + \" \")\n        else:\n            params += addnodes.desc_name(name, name)\n        for arg in args.split():\n            params += addnodes.desc_parameter(arg, arg)\n        signode += params\n        return name\n\n\nclass ELispVariable(ELispMarkup):\n    def get_index_text(self, objectname, name):\n        return \"{} (variable)\".format(name)\n\n    def handle_signature(self, sig, signode):\n        signode += addnodes.desc_name(sig, sig)\n        return sig\n\n\nclass ELispCommand(ELispMarkup):\n    option_spec = {\n        'kbd': lambda x: x\n    }\n\n    def get_index_text(self, objectname, name):\n        return \"{} (command)\".format(name)\n\n    def handle_signature(self, sig, signode):\n        kbd = self.options.get(\"kbd\")\n        name = sig\n        if kbd:\n            description = \"{} ({})\".format(kbd, name)\n        else:\n            description = \"M-x {}\".format(sig)\n\n        signode += addnodes.desc_name(description, description)\n        return name\n\n\nclass ELispOption(ELispMarkup):\n    option_spec = {\n        'default': lambda x: x\n    }\n\n    def get_index_text(self, objectname, name):\n        return \"{} (customize option)\".format(name)\n\n    def handle_signature(self, sig, signode):\n        default = self.options.get(\"default\")\n        if default:\n            description = \"{} [{}]\".format(sig, default)\n        else:\n            description = sig\n        signode += addnodes.desc_name(description, description)\n        return sig\n\n\nclass ELispDomain(Domain):\n    \"\"\"Emacs Lisp language domain.\"\"\"\n    name = 'el'\n    label = 'ELisp'\n\n    object_types = {\n        'function': ObjType(_('function'), 'func'),\n        'variable': ObjType(_('variable'), 'var'),\n        'command': ObjType(_('command'), 'cmd'),\n        'option': ObjType(_('variable'), 'opt'),\n    }\n    directives = {\n        'function': ELispFunction,\n        'variable': ELispVariable,\n        'command': ELispCommand,\n        'option': ELispOption,\n    }\n    roles = {\n        'func': XRefRole(),\n        'var': XRefRole(),\n        'cmd': XRefRole(),\n        'opt': XRefRole(),\n    }\n    initial_data = {\n        'objects': {},  # fullname, type -> docname\n    }\n\n    def clear_doc(self, docname):\n        for (fullname, type_), docname in self.data['objects'].items():\n                if fullname == docname:\n                    del self.data['objects'][fullname]\n\n    def resolve_xref(self, env, fromdocname, builder, type_, target, node,\n                     contnode):\n        objects = self.data['objects']\n        objtypes = self.objtypes_for_role(type_)\n        for objtype in objtypes:\n            if (objtype, target) in objects:\n                return make_refnode(builder, fromdocname,\n                                    objects[objtype, target],\n                                    objtype + \"-\" + target,\n                                    contnode, target + \" \" + objtype)\n\n    def get_objects(self):\n        for (name, type_), docname in self.data['objects'].items():\n            yield name, name, type_, docname, type_ + '-' + name, 1\n\n\ndef setup(app):\n    app.add_domain(ELispDomain)\n"
  },
  {
    "path": "docs/usage.org",
    "content": "#+TITLE: Usage\n#+AUTHOR: David Landell\n#+EMAIL: david.landell@sunnyhill.email\n#+DATE: 2019\n#+LANGUAGE: en\n#+OPTIONS: broken-links:auto, toc:nil, email:nil, num:nil, ^:nil, author:nil, date:nil\n\n#+INCLUDE: \"utils.org\"\n\n* Installation\n  :PROPERTIES:\n  :CUSTOM_ID: installation\n  :END:\n  This version of /rg/ is supported on GNU Emacs\n  {{{elisp((rg-emacs-min-version))}}} or later on Linux systems. It\n  might work on older Emacsen and on other systems but such\n  configurations are not tested. Patches for other OS:es are welcome.\n\n  :RUBRIC:\n  MELPA\n  :END:\n  Packages are published on [[https://stable.melpa.org/#/rg][MELPA Stable]] and [[http://melpa.org/#/rg][MELPA]]. From within Emacs,\n  run =M-x package-install [RET] rg [RET]= to install from those\n  sources.\n\n  Enable default key bindings:\n  #+BEGIN_SRC elisp\n      (rg-enable-default-bindings)\n  #+END_SRC\n  The above will enable the default key map\n  {{{elisp_code((rg-default-keymap))}}} under the default prefix key\n  {{{elisp_code((edmacro-format-keys rg-keymap-prefix))}}}.\n\n  :RUBRIC:\n  Manual\n  :END:\n  Releases can alternatively be downloaded from [[https://github.com/dajva/rg.el/releases/latest][GitHub]] and installed\n  manually. Put all elisp files in main directory in your load path\n  and =require= the package in your init file.\n\n  #+BEGIN_SRC elisp\n      (require 'rg)\n      (rg-enable-default-bindings)\n  #+END_SRC\n\n  You would also need to make sure all package requirements are\n  met. For this version these are:\n  #+BEGIN_SRC elisp :results value raw :exports results\n      (mapconcat\n       (lambda (dep)\n         (format \"- *%s* _%s_\" (car dep) (cdr dep)))\n       rg-package-deps\n       \"\\n\")\n  #+END_SRC\n\n  /rg/ is using autoloaded symbols which means it's also possible\n  to defer loading if you have autoloading setup. That usually comes\n  out of the box with =package-install=.\n\n  :RUBRIC:\n  Lazy loading\n  :END:\n  For lazy loading you don't want to call directly into the package\n  during startup. Use a setup similar to this instead:\n\n  #+BEGIN_SRC elisp\n    (global-set-key (kbd \"C-c s\") #'rg-menu)\n    (with-eval-after-load 'rg\n       ;; Your settings goes here.\n    )\n  #+END_SRC\n\n  If you don't want to use the transient menu interface, the following\n  is needed to achieve lazy loading:\n  #+BEGIN_SRC elisp\n    ;; Workaround for emacs' lack of autoloaded keymaps.\n    ;; This is essentially what use-package do.\n    (defun rg-autoload-keymap ()\n      (interactive)\n      (if (not (require 'rg nil t))\n          (user-error (format \"Cannot load rg\"))\n        (let ((key-vec (this-command-keys-vector)))\n          (global-set-key key-vec rg-global-map)\n          (setq unread-command-events\n                (mapcar (lambda (ev) (cons t ev))\n                        (listify-key-sequence key-vec))))))\n\n    (global-set-key (kbd \"C-c s\") #'rg-autoload-keymap)\n    (with-eval-after-load 'rg\n       ;; Your settings goes here.\n    )\n  #+END_SRC\n\n  :RUBRIC:\n  wgrep\n  :END:\n  This package use [[https://github.com/mhayashi1120/Emacs-wgrep][wgrep]] for editing capabilities in the rg results\n  buffer. No setup is needed.\n\n  :RUBRIC:\n  Isearch integration\n  :END:\n  Optional [[#isearch_search][isearch integration]] can be enabled to allow you to extend\n  isearch to trigger ripgrep searching.\n  Enable it in your configuration with:\n  #+BEGIN_SRC elisp\n    (require 'rg-isearch)\n    (define-key isearch-mode-map \"\\M-sr\" 'rg-isearch-menu)\n  #+END_SRC\n  For the evil use case where isearch-mode is exited after first search hit,\n  users would also want to add the binding to the =global-map= or\n  similar.\n\n  :RUBRIC:\n  Interaction with the /ripgrep/ configuration file\n  :END:\n  The /ripgrep/ binary allows using a [[https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md#configuration-file][configuration file]] to set\n  default values for command line flags. This package requires\n  specific command line flags to function correctly and using a\n  /ripgrep/ configuration may conflict with these requirements. Therefore\n  the configuration file is ignored by default. This can be changed\n  by the [[opt:rg-ignore-ripgreprc][rg-ignore-ripgreprc]] setting.\n\n  :NOTE:\n  Using the /ripgrep/ configuration file may break functionality of this\n  package if you are not careful.\n  :END:\n\n  :RUBRIC:\n  Interaction with xterm-color\n  :END:\n  This package is not written to be used with custom output colors\n  provided by external packages like /xterm-color/. It relies on the\n  color escape sequences so stripping these will break in unexpected\n  ways.\n  If you are using such packages, the advice is to hook such\n  functionality into =compilation-filter-hook= instead of advising\n  =compilation-filter=.\n\n* Searching\n  :PROPERTIES:\n  :CUSTOM_ID: searching\n  :END:\n  Searching is done by invoking one of the different frontend\n  commands. This package is built around recursive search based on three\n  parameters; a single /directory/, /file type/ filter, and a search\n  /pattern/. These three parameters can interactively be selected or\n  figured out automatically by the package, depending on which command\n  that is used.\n\n  The underlying /ripgrep/ binary has the file type filter concept\n  built in. You have a high level of control over which files to\n  search and which to ignore. This is partly what makes it so fast,\n  ignoring uninteresting files.\n\n  In addition to the base parameters there are a lot of options that\n  control how a search is done. These are typically selected from the\n  [[#the_menu][rg-menu]] interface.\n\n*** Case sensitivity\n    Considering case when searching is an important feature of any\n    search tool. This package gives you a lot of control over how to\n    handle case sensitive and case insensitive search. It can be\n    forced to *on* or *off* and set to *smart case*. The latter is\n    similar to the /ripgrep/ =--smart-case= flag but is not using the\n    flag directly. One thing to note about this is that the case\n    insensitive setting controls the behavior when starting a new\n    search. In the results buffer the setting is fixed to *on* or\n    *off* but can be toggled easily with a key binding. See\n    [[opt:rg-ignore-case][rg-ignore-case]] customization for the details of the configuration.\n\n*** Interactive search\n    :PROPERTIES:\n    :CUSTOM_ID: basic_search\n    :END:\n    Two commands implements fully interactive search, where all the\n    base parameters are selected from the mini buffer.\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg 'rg-global-map)\n    #+END_SRC\n    This command prompts for /query/, /file type/ and /directory/ and\n    tries to suggest reasonable default values.\n    The /query/ string is interpreted as a regular expression. Default\n    for /query/ is the thing at point and for /directory/ it is the current\n    directory.\n    If the type of the currently visited file is recognized, the\n    corresponding [[#file_type_aliases][file type alias]] is suggested as the /file type/\n    parameter.\n\n    Invoking this command with the /universal argument/ will trigger\n    confirmation and potential modification of the [[#full_command_line_search][full command line]]\n    that will invoke the /ripgrep/ binary.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-literal 'rg-global-map)\n    #+END_SRC\n    This command works in the same way as [[cmd:rg][rg]] but interprets the /query/\n    string literally and not as a regular expression.\n\n    Invoking this command with the /universal argument/ will trigger\n    confirmation and potential modification of the [[#full_command_line_search][full command line]]\n    that will invoke the /ripgrep/ binary.\n    :END:\n*** Project search\n    :PROPERTIES:\n    :CUSTOM_ID: project_search\n    :END:\n    A common scenario is to search through a whole project while\n    visiting a file in the project. This essentially means identifying\n    the project root and use that as the top /directory/ when invoking\n    the /ripgrep/ binary. /rg/ supports several ways of identifying a\n    project. Emacs' major project packages are supported including\n    [[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\n    none of these are used, the fallback is Emacs' =vc-backend=.\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-project 'rg-global-map)\n    #+END_SRC\n    Search in the current project. The /directory/ is selected via one\n    of Emacs' project packages while /query string/ and /file type/\n    are prompted for. The /query string/ is interpreted as a regular\n    expression.\n    :END:\n*** Do what I mean\n    :PROPERTIES:\n    :CUSTOM_ID: do_what_i_mean\n    :END:\n    The *DWIM* family of search commands tries to be smart by figure\n    out the search parameters from the context without\n    prompting. Thanks to /ripgrep's/ speed, this allows for new ways of\n    searching by invoking a dwim command and then /refine/ the\n    search from the results buffer.\n\n    These commands use the word (with the definition of word depending\n    on context) under cursor as the /query/ string. The /file type/\n    parameter is taken from the type of the currently visited file. If\n    the current file type can not be identified all file types known\n    to /ripgrep/ are used. The fallback can be customized with\n    [[opt:rg-default-alias-fallback]]. The /directory/ parameter varies\n    between these commands.\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-dwim-project-dir 'rg-global-map)\n    #+END_SRC\n    Do a *DWIM* search in the current [[#project_search][project]].\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-dwim-current-dir 'rg-global-map)\n    #+END_SRC\n    Do a *DWIM* search in the current directory.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-dwim-current-file 'rg-global-map)\n    #+END_SRC\n    Do a *DWIM* search in the current file. The /current file/ in this\n    context is actually a file /pattern/ exactly matching the current\n    file name in a search starting from current directory. Most of the\n    time this means a single file but if there are multiple files with\n    the same name in a sub directory, those will be searched as well.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-dwim 'rg-global-map)\n    #+END_SRC\n    This command combines all the *DWIM* commands to one. The default\n    search is in the [[cmd:rg-dwim-project-dir][project dir]]. With one /universal argument/ [[cmd:rg-dwim-current-dir][current\n    directory]] is used and with double /universal arguments/ a [[cmd:rg-dwim-current-file][file\n    search]] is done.\n    :END:\n*** Isearch search\n    :PROPERTIES:\n    :CUSTOM_ID: isearch_search\n    :END:\n    Isearch integration is optional and need to be enabled explicitly\n    in your emacs configuration. See [[#installation][installation]] for more info.\n\n    This functionality is similar to emacs built in occur package but offers\n    some additional choices for the search and provides the full\n    functionality of the rg search result buffer.\n    When enabled, the choosen binding can be used from isearch to\n    trigger a menu for extending the isearch to do a ripgrep search in\n    current file, current directory or current project.\n\n*** File type aliases\n    :PROPERTIES:\n    :CUSTOM_ID: file_type_aliases\n    :END:\n    File type aliases are used in /ripgrep/ to filter out the files\n    to search in. The /ripgrep/ binary comes with a default set\n    of aliases that can be extended or overridden from this package by\n    customizing [[opt:rg-custom-type-aliases]].\n\n    An alias is a mapping between a name and a list of [[https://en.wikipedia.org/wiki/Glob_%2528programming%2529][glob patterns]]\n    matching the files of interest. Selecting an alias when searching\n    is done with completing read of the defined aliases. It is also\n    possible to enter a custom glob pattern if there is no suitable\n    alias defined for the file type.\n\n    /rg/ defines some internal aliases:\n\n    | Name         | Meaning                                                           |\n    |--------------+-------------------------------------------------------------------|\n    | *all*        | all defined types including [[opt:rg-custom-type-aliases][rg-custom-type-aliases]]                |\n    | *everything* | all files. No filtering on type is done.                          |\n    | *custom*     | used internally in this package for mapping custom glob patterns. |\n    |--------------+-------------------------------------------------------------------|\n\n    :WARNING:\n    Do not use any of the internal aliases in [[opt:rg-custom-type-aliases][rg-custom-type-aliases]].\n    That would interfere with the package internal usage.\n    :END:\n\n*** The menu\n    :PROPERTIES:\n    :CUSTOM_ID: the_menu\n    :END:\n    The global [[opt:rg-keymap-prefix][prefix key]] may be bound to a transient\n    prefix command, which means that the key binding will popup a\n    menu. This package is using the same popup menu backend called\n    [[https://magit.vc/manual/transient][transient]] as the [[https://magit.vc/manual/magit][magit]] package. If you are familiar with magit\n    this should feels like home.\n\n    The menu is mostly interesting when you want to give specific\n    command line flags to the /ripgrep/ binary. When you just want to do\n    a quick search based on the defaults the menu basically acts as a\n    normal keymap.\n\n    Pressing the =rg-menu= [[opt:rg-keymap-prefix][prefix key]] will popup the menu where command\n    line flags can be selected before triggering the wanted search\n    function. The menu can be customized via the transient API as\n    usual. This package contains some shortcuts to directly add a new\n    command to the menu when defining the command via the\n    [[func:rg-define-search]] macro.\n\n    #+BEGIN_SRC elisp\n      (rg-define-search rg-word\n        :format literal\n        :flags (\"--word-regexp\")\n        :menu (\"Custom\" \"w\" \"Word\"))\n    #+END_SRC\n\n    The =:menu= keyword in the above invocation will trigger insertion\n    of a new menu item bound to key =w= with description *Word*. The\n    new menu item will be put under the *Custom* group. This group is\n    not available in the original menu so it will be created.\n\n    The menu can be triggered from the [[#results_buffer][results buffer]] with the =m= key.\n    The commands in the menu differs, depending on from where it's\n    triggered but the available options are the same. The menu does\n    not show all options by default.\n\n    The visible options can be controlled by the transient suffix\n    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\n    level 4 press =C-x l= to enter edit mode when the menu is\n    visible. Then select the option by pressing the key sequence that\n    activates the option and choose the level 4 for that option. It's\n    also possible to use the transient edit mode for modifying the\n    overall level of the menu to enable more options at once.\n\n* Results buffer\n  :PROPERTIES:\n  :CUSTOM_ID: results_buffer\n  :END:\n  The results of a search is shown in the results buffer. This buffer\n  displays search parameters, the full command line and the output of\n  the /ripgrep/ binary. It supports basic navigation between search\n  results editing of the file contents directly from the search\n  buffer and also modification of the current search. The results\n  buffer is a modified /compilation/ buffer and some key bindings and\n  functionality is inherited from the parent and from /grep mode/.\n\n*** Navigation\n    Navigation works mostly as in grep/compilation buffers.\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'compilation-next-error 'rg-mode-map (kbd \"M-n\"))\n    #+END_SRC\n    Move to next line with a match.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'compilation-previous-error 'rg-mode-map (kbd \"M-p\"))\n    #+END_SRC\n    Move to previous line with a match.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'next-error-no-select 'rg-mode-map)\n    #+END_SRC\n    Move to next line with a match, show that file in other buffer and highlight the\n    match.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'previous-error-no-select 'rg-mode-map)\n    #+END_SRC\n    Move to previous line with a match, show that file in other buffer and highlight the\n    match.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-next-file 'rg-mode-map)\n    #+END_SRC\n    Move to next file header if the results is grouped under a file\n    header (See [[opt:rg-group-result]]).\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-prev-file 'rg-mode-map)\n    #+END_SRC\n    Move to previous file header if the results is grouped under a file\n    header (See [[opt:rg-group-result]]).\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'compilation-next-file 'rg-mode-map)\n    #+END_SRC\n    Move first match in previous file.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'compilation-previous-file 'rg-mode-map)\n    #+END_SRC\n    Move last match in previous file.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'compile-goto-error 'rg-mode-map)\n    #+END_SRC\n    Visit match in file.\n    :END:\n\n    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\n    jump across files.\n\n*** Refine search\n    From the results buffer it's easy to change the search\n    parameters. Some bindings toggle a flag while others allow you to\n    interactively change the [[#searching][base\n    parameters]].\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-rerun-change-dir 'rg-mode-map)\n    #+END_SRC\n    Interactively change search /directory/.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-rerun-change-files 'rg-mode-map)\n    #+END_SRC\n    Interactively change searched /file types/.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-rerun-change-literal 'rg-mode-map)\n    #+END_SRC\n    Interactively change /search string/ interpret the string literally.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-rerun-change-regexp 'rg-mode-map)\n    #+END_SRC\n    Interactively change /search string/ interpret the string as a regular\n    expression.\n    :END:\n\n    :TIP:\n    [[cmd:rg-rerun-change-regexp]] and [[cmd:rg-rerun-change-literal]] are\n    used for switching between regular expression and literal\n    search. So for quick switching between search modes with the same\n    search string,  just press the respective key and then =RET=.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-recompile 'rg-mode-map)\n    #+END_SRC\n    Rerun the current search without changing any parameters.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-rerun-toggle-case 'rg-mode-map)\n    #+END_SRC\n    Toggle case sensitivity of search. The state of the flag is shown\n    in the *[case]* header field.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-rerun-toggle-ignore 'rg-mode-map)\n    #+END_SRC\n    Toggle if ignore files are respected. The state of the flag is shown\n    in the *[ign]* header field.\n    :END:\n\n    :TIP:\n    It is possible to create and bind your own toggle flags with the\n    macro [[func:rg-define-toggle]].\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-menu 'rg-mode-map)\n    #+END_SRC\n    Fire up [[#the_menu][the menu]] for full access to options and flags.\n    :END:\n\n\n*** Full command line search\n    :PROPERTIES:\n    :CUSTOM_ID: full_command_line_search\n    :END:\n    Some search commands (See [[cmd:rg]] or [[cmd:rg-literal]]) allow you to\n    edit the final command line before invoking the search by giving a\n    /universal argument/. This can be used to invoke features of the\n    /ripgrep/ binary that is not supported in this package's\n    interface. This could be specific flags, searching in multiple\n    directories etc.\n\n    :NOTE:\n    Using full command line search will disable refinement of the\n    search from the result buffer.\n    :END:\n\n*** History navigation\n    :PROPERTIES:\n    :CUSTOM_ID: history_navigation\n    :END:\n    Each search result is stored in the search history, which is a per\n    results buffer property. History can be navigated back and\n    forward, the forward history is cleared when a new search is done.\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-back-history 'rg-mode-map)\n    #+END_SRC\n    Navigate back in history.\n    :END:\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'rg-forward-history 'rg-mode-map)\n    #+END_SRC\n    Navigate forward in history.\n    :END:\n\n    :TIP:\n    The key bindings here are slightly inconvenient so invoking this\n    via [[#the_menu][the menu]] by pressing =m b= and =m w= is more ergonomic.\n    :END:\n\n*** Edit and apply (wgrep)\n    :PROPERTIES:\n    :CUSTOM_ID: edit_and_apply\n    :END:\n    The results buffer supports inline editing via the [[https://github.com/mhayashi1120/Emacs-wgrep][wgrep]]\n    package. This is setup automatically when /rg/ is loaded.\n\n    :COMMAND:\n    #+BEGIN_SRC elisp :results value raw :exports results\n    (rg-command-info #'wgrep-change-to-wgrep-mode 'rg-mode-map)\n    #+END_SRC\n    Make the search results editable by enabling =wgrep= mode.\n    When done press =C-c C-c= to commit your changes to the underlying\n    files or =C-c C-k= to drop the changes.\n    :END:\n\n* Search management\n  :PROPERTIES:\n  :CUSTOM_ID: search_management\n  :END:\n  The result buffer is named {{{elisp_code((format \"\\*%s\\*\"\n  rg-buffer-name))}}} and /rg/ reuse the same result buffer for new\n  searches. If you want to store a search while continuing doing new searches\n  there are two ways of doing that.\n\n  :COMMAND:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-command-info #'rg-save-search 'rg-mode-map)\n  #+END_SRC\n  Save the search buffer by renaming it to a unique new name.\n  This is available both outside and inside a result buffer. Outside\n  of the result buffer it's bound to\n  {{{elisp_code((rg-key-for-command #'rg-save-search 'rg-global-map))}}}.\n\n  If you want to keep all search buffers until manually killed you can\n  use this snippet in your init file.\n  #+BEGIN_SRC elisp\n    (defadvice rg-run (before rg-run-before activate)\n      (rg-save-search))\n  #+END_SRC\n  :END:\n\n  :COMMAND:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-command-info #'rg-save-search-as-name 'rg-mode-map)\n  #+END_SRC\n  Save the search buffer and interactively give it a specific name.\n  This is available both outside and inside a result buffer. Outside\n  of the result buffer it's bound to\n  {{{elisp_code((rg-key-for-command #'rg-save-search-as-name 'rg-global-map))}}}.\n  :END:\n\n  The default buffer name can be customized with [[opt:rg-buffer-name]]. This\n  setting considers dir local variables and it's even possible to use\n  a function to get a really dynamic setup.\n\n  Having a lot of search buffers floating around can easily get\n  messy. To help keeping this under control there is a search\n  manager. The manager is simply a modified =ibuffer= that lists all\n  the results buffers, shows some data about the searches and make it\n  possible to kill of some unused etc.\n\n  :COMMAND:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-command-info #'rg-list-searches 'rg-mode-map)\n  #+END_SRC\n  Open the search manager.\n  This is available both in result buffer and globally bound to\n  {{{elisp_code((rg-key-for-command #'rg-list-searches 'rg-global-map))}}}.\n  :END:\n\n  :COMMAND:\n  #+BEGIN_SRC elisp :results value raw :exports results\n  (rg-command-info #'rg-kill-saved-searches 'rg-global-map)\n  #+END_SRC\n  Kill all saved searches except for the one that matches [[opt:rg-buffer-name]].\n  This is available both in result buffer and globally bound to\n  {{{elisp_code((rg-key-for-command #'rg-kill-saved-searches 'rg-global-map))}}}.\n  :END:\n\n  :WARNING:\n  If you have a dynamic [[opt:rg-buffer-name]] setup, only one buffer that\n  matches your current criteria (dir locals or project for instance)\n  will be kept. So be careful when killing saved searches to avoid\n  losing important search results.\n  :END:\n\n* Multi line search\n  :PROPERTIES:\n  :CUSTOM_ID: multi_line_search\n  :END:\n  By default, ripgrep does matching per line. The =--multiline= flag\n  can be used for enabling matching over multiple lines. This\n  flag is available in the [[#the_menu][rg-menu]] as an option. The =--multiline=\n  flag does not match new line characters with the =.= as one might\n  expect though. A separate flag is used to allow this,\n  =--multiline-dotall=. The casual user of multi line search commonly\n  want this flag on by default so it's recommended to add this to\n  [[opt:rg-command-line-flags]] to avoid having to trigger this flag\n  manually from the menu.\n\n  See the ripgrep manual page for more info about the multi line\n  flags.\n"
  },
  {
    "path": "docs/utils.org",
    "content": "#+MACRO: elisp src_elisp[:results value raw :exports results]{$1}\n#+MACRO: elisp_code src_elisp[:results value :exports results]{$1}\n\n#+NAME: utils\n#+BEGIN_SRC elisp :results output drawer :exports none\n  (require 'cl-lib)\n  (require 'cus-edit)\n  (require 'edmacro)\n  (require 'help)\n  (require 'package)\n  (require 'rg)\n\n  (defvar rg-package-version nil)\n  (defvar rg-package-deps nil)\n  (rg-enable-menu)\n\n  (defun rg-package-info ()\n    (let ((file-name \"../rg.el\"))\n      (with-temp-buffer\n        (insert-file-contents file-name)\n        (condition-case nil\n            (package-buffer-info)\n          (error \"Invalid package\")))))\n\n  (defun rg-extract-package-info ()\n    (let ((desc (rg-package-info)))\n      (setf rg-package-version (package-version-join (package-desc-version desc)))\n      (dolist (req (package-desc-reqs desc))\n        (push (cons (car req) (package-version-join (cadr req))) rg-package-deps))))\n\n  (defun rg-package-deps ()\n    (when (not rg-package-deps)\n      (rg-extract-package-info))\n    rg-package-deps)\n\n  (defun rg-package-version ()\n    (when (not rg-package-version)\n      (rg-extract-package-info))\n    rg-package-version)\n\n  (defun rg-emacs-min-version ()\n    (cdr (assq 'emacs (rg-package-deps))))\n\n  (defun rg-default-keymap ()\n    (if rg-use-transient-menu\n        \"rg-menu\"\n      \"rg-global-map\"))\n\n  (defun rg-custom-info (sym &optional default)\n    (let* ((type (custom-variable-type sym))\n           (value (or default\n                      (if (and (consp type) (eq (car type) 'key-sequence))\n                          (edmacro-format-keys (symbol-value sym))\n                        (symbol-value sym)))))\n      (format \"%s\\n:default: %S\" sym value)))\n\n  (defun rg-face-info (face)\n    (cl-assert (facep face))\n    (format \"%s\\n:default: %s\" face (face-attribute face :inherit)))\n\n  (defun rg-key-for-command (sym map &optional wanted-key)\n    (cl-assert (commandp sym))\n    (when-let ((keys (where-is-internal sym (symbol-value map))))\n      (let* ((key (edmacro-format-keys (or\n                                        (and wanted-key\n                                             (cl-find wanted-key keys :test 'equal))\n                                        (car keys))))\n             (prefix (when (and key\n                                (eq map 'rg-global-map))\n                       (edmacro-format-keys rg-keymap-prefix))))\n        (if prefix\n            (format \"%s %s\" prefix key)\n          (format \"%s\" key)))))\n\n  (defun rg-command-info (sym map &optional wanted-key)\n    (if-let ((key-sequence (rg-key-for-command sym map wanted-key)))\n        (format \"%s\\n:kbd: %s\" sym key-sequence)\n      (format \"%s\\n\" sym)))\n\n  (defun rg-function-info (sym)\n    (cl-assert (fboundp sym))\n    (let ((args (mapconcat #'symbol-name (help-function-arglist sym) \" \")))\n      (format \"(%s %s)\\n\" sym args)))\n#+END_SRC\n\ncall_utils()\n\n#+BEGIN_EXPORT rst\n.. default-domain:: el\n#+END_EXPORT\n"
  },
  {
    "path": "rg-header.el",
    "content": ";;; rg-header.el --- Header line for rg-mode -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;; Header line format for rg-mode result buffer.\n\n;;; Code:\n\n(require 'mouse)\n\n(declare-function rg-cur-search-pattern \"rg-result.el\")\n\n\f\n;; Customization\n(defcustom rg-header-max-search-string-length nil\n  \"The max line length of header line search string item.\"\n  :type '(choice (const :tag \"Don't truncate\" nil)\n                 (number :tag \"The max width\"))\n  :group 'rg)\n\n\f\n;; Faces\n(defface rg-toggle-on-face\n  '((t :inherit rg-file-tag-face))\n  \"face for toggle \\\"on\\\" text in header.\"\n  :group 'rg-face)\n\n(defface rg-toggle-off-face\n  '((t :inherit rg-error-face))\n  \"face for toggle \\\"off\\\" text in header.\"\n  :group 'rg-face)\n\n(defface rg-literal-face\n  '((t :inherit rg-filename-face))\n  \"face for literal label in header.\"\n  :group 'rg-face)\n\n(defface rg-regexp-face\n  '((t :inherit compilation-line-number))\n  \"face for regexp label in header.\"\n  :group 'rg-face)\n\n\f\n;; Defuns\n(defun rg-header-render-label (labelform)\n  \"Return a fontified header label.\nLABELFORM is either a string to render or a form where the `car' is a\nconditional and the two following items are then and else specs.\nSpecs are lists where the the `car' is the labels string and the\n`cadr' is font to use for that string.\"\n  (list '(:propertize \"[\" font-lock-face (header-line bold))\n        (cond\n         ((stringp labelform)\n          `(:propertize ,labelform font-lock-face (header-line bold)))\n         ((listp labelform)\n          (let* ((condition (nth 0 labelform))\n                 (then (nth 1 labelform))\n                 (else (nth 2 labelform)))\n            `(:eval (if ,condition\n                        (propertize ,(nth 0 then) 'font-lock-face '(,(nth 1 then) header-line bold))\n                      (propertize ,(nth 0 else) 'font-lock-face '(,(nth 1 else) header-line bold))))))\n         (t (error \"Not a string or list\")))\n        '(:propertize \"]\" font-lock-face (header-line bold))\n        '(\": \")))\n\n(defun rg-header-render-toggle (on)\n  \"Return a fontified toggle symbol.\nIf ON is non nil, render \\\"on\\\" string, otherwise render \\\"off\\\"\nstring.\"\n  `(:eval (let* ((on ,on)\n                 (value (if on \"on \" \"off\"))\n                 (face (if on 'rg-toggle-on-face 'rg-toggle-off-face)))\n            (propertize value 'font-lock-face `(bold ,face)))))\n\n(defun rg-header-mouse-action (command help &rest items)\n  \"Add a keymap with mouse click action for COMMAND.\nWhen hoovering HELP is shown as a tooltip.  ITEMS is the header line\nitems that the map will be applied to.\"\n  (let ((map (make-sparse-keymap)))\n    (define-key map\n      (if (or (> emacs-major-version 30)\n              (and (= emacs-major-version 30) (>= emacs-minor-version 2)))\n          [header-line mouse-1]\n        [header-line mouse-2])\n      (lambda (click)\n        (interactive \"e\")\n        (mouse-select-window click)\n        (call-interactively command)))\n    `(:propertize ,items mouse-face header-line-highlight\n                  help-echo ,help\n                  keymap ,map)))\n\n(defun rg-header-truncate-search-pattern (search)\n  \"Truncate SEARCH if it exceeds `rg-header-max-search-string-length'.\"\n  (if (rg-header-truncates-p search)\n      (truncate-string-to-width search\n                                rg-header-max-search-string-length\n                                0\n                                nil\n                                t)\n    search))\n\n(defun rg-header-truncates-p (search)\n  \"Verify that SEARCH would be truncated.\"\n  (and (numberp rg-header-max-search-string-length)\n       (< rg-header-max-search-string-length (length search))))\n\n(defun rg-header-search-help ()\n  \"Get the search help for the current buffer.\"\n  (let ((pattern (rg-cur-search-pattern)))\n\n    (if (rg-header-truncates-p pattern)\n        (concat \"Change search string: \" pattern)\n      \"Change search string\")))\n\n;; Use full-command here to avoid dependency on rg-search\n;; struct. Should be properly fixed.\n(defun rg-create-header-line (search full-command)\n  \"Create the header line for SEARCH.\nIf FULL-COMMAND specifies if the full command line search was done.\"\n  (let ((itemspace \"  \"))\n    (setq header-line-format\n          (if full-command\n              (list (rg-header-render-label \"command line\") \"no refinement\")\n            (list\n             (rg-header-mouse-action\n              'rg-rerun-toggle-rexexp-literal \"Toggle literal/regexp\"\n              (rg-header-render-label `((rg-search-literal ,search)\n                                        (\"literal\" rg-literal-face)\n                                        (\"regexp\" rg-regexp-face))))\n             (rg-header-mouse-action\n              'rg-rerun-change-query (rg-header-search-help)\n              `(:eval (rg-header-truncate-search-pattern (rg-search-pattern ,search))))\n             itemspace\n             (rg-header-render-label \"files\")\n             (rg-header-mouse-action\n              'rg-rerun-change-files \"Change file types\"\n              `(:eval (rg-search-files ,search)))\n             itemspace\n             (rg-header-render-label \"case\")\n             (rg-header-mouse-action\n              'rg-rerun-toggle-case \"Toggle case\"\n              (rg-header-render-toggle\n               `(not (member \"-i\" (rg-search-flags ,search)))))\n             itemspace\n             (rg-header-render-label \"ign\")\n             (rg-header-mouse-action\n              'rg-rerun-toggle-ignore \"Toggle ignore\"\n              (rg-header-render-toggle\n               `(not (member \"--no-ignore\" (rg-search-flags ,search)))))\n             itemspace\n             (rg-header-render-label \"hits\")\n               '(:eval (format \"%d\" rg-hit-count)))))))\n\n(provide 'rg-header)\n\n;;; rg-header.el ends here\n"
  },
  {
    "path": "rg-history.el",
    "content": ";;; rg-history.el --- History navigation in rg.el -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;;; Code:\n\n(require 'cl-lib)\n(require 'subr-x)\n\n(cl-defstruct (rg-history (:constructor rg-history-create)\n                          (:copier nil))\n  past                    ; list of searches for backward navigation\n  present                 ; current search\n  future)                 ; list of searches for forward navigation\n\n(defun rg-history-push (item instance)\n  \"Push a new ITEM to the rg-history INSTANCE.\"\n  (when-let (present (rg-history-present instance))\n    (push present (rg-history-past instance)))\n  (setf (rg-history-present instance) item)\n  (setf (rg-history-future instance) nil))\n\n(defun rg-history-back (instance)\n  \"Move back in the rg-history INSTANCE.\nReturn the new current search.\"\n  (when-let (prev (pop (rg-history-past instance)))\n    (push (rg-history-present instance) (rg-history-future instance))\n    (setf (rg-history-present instance) prev)))\n\n(defun rg-history-forward (instance)\n  \"Move forward in the rg-history INSTANCE.\nReturn the new current search.\"\n  (when-let (next (pop (rg-history-future instance)))\n    (push (rg-history-present instance) (rg-history-past instance))\n    (setf (rg-history-present instance) next)))\n\n(provide 'rg-history)\n\n;;; rg-history.el ends here\n"
  },
  {
    "path": "rg-ibuffer.el",
    "content": ";;; rg-ibuffer.el --- List search buffers for rg-mode -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;; Use ibuffer to list active searches.\n\n;;; Code:\n\n(require 'ibuf-ext)\n(require 'ibuffer)\n(require 'rg-result)\n\n(defconst rg-search-list-buffer-name \"*Searches rg*\")\n\n(defun rg-ibuffer-search-updated()\n  \"This function is executed when search list buffer is updated.\"\n  (when-let ((list-buffer (get-buffer rg-search-list-buffer-name)))\n    (ignore-errors\n      (with-current-buffer list-buffer\n        (ibuffer-update nil t)))))\n\n(defun rg-ibuffer-buffer-killed ()\n  \"Function run when the search list buffer is killed.\"\n  (remove-hook 'rg-filter-hook #'rg-ibuffer-search-updated))\n\n(define-ibuffer-column rg-search-term\n  (:name \"Search\" :props ('face 'rg-match-face))\n  (ignore mark)\n  (if rg-cur-search\n      (rg-search-pattern rg-cur-search)\n    \"N/A\"))\n\n(define-ibuffer-column rg-hit-count\n  (:name \"Hits\")\n  (ignore mark)\n  (number-to-string rg-hit-count))\n\n(define-ibuffer-column rg-search-dir\n  (:name \"Directory\" :props ('face 'rg-filename-face))\n  (ignore mark)\n  (if rg-cur-search\n      (rg-search-dir rg-cur-search)\n    \"N/A\"))\n\n(define-ibuffer-column rg-file-types\n  (:name \"Type\")\n  (ignore mark)\n  (if rg-cur-search\n      (rg-search-files rg-cur-search)\n    \"N/A\"))\n\n;;;###autoload\n(defun rg-list-searches ()\n  \"List all `rg-mode' buffers in `ibuffer'.\"\n  (interactive)\n  (let ((other-window (equal current-prefix-arg '(4))))\n    (ibuffer other-window rg-search-list-buffer-name '((mode . rg-mode)) nil nil nil\n             '((mark \" \"\n                     (name 16 16 nil :elide) \" \"\n                     (rg-search-term 18 18 nil :elide) \" \"\n                     (rg-hit-count 7 7) \" \"\n                     (rg-file-types 7 7) \" \"\n                     (process 10 10)\n                     (rg-search-dir 20 -1 nil :elide) \" \")))\n    (add-hook 'rg-filter-hook #'rg-ibuffer-search-updated)\n    (with-current-buffer rg-search-list-buffer-name\n      (ibuffer-auto-mode)\n      (set (make-local-variable 'ibuffer-use-header-line) nil)\n      (ibuffer-clear-filter-groups)\n      (add-hook 'kill-buffer-hook #'rg-ibuffer-buffer-killed nil t))))\n\n(provide 'rg-ibuffer)\n\n;;; rg-ibuffer.el ends here\n"
  },
  {
    "path": "rg-info-hack.el",
    "content": ";;; rg-info-hack.el --- Make sure rg.el info documentation looks good -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2019 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;;; Code:\n(require 'info)\n\n(define-advice info-insert-file-contents\n    (:after (&rest _) sphinx-info-insert-file-contents)\n  \"Hack to hide \\\"See\\\" in references.\nThis makes `Info-hide-note-references' buffer-local and\nautomatically set to `hide' iff it can be determined that this file\nis the rg.el documentation and was created from a Texinfo file\n  generated by Sphinx.\"\n  (set (make-local-variable\n\t'Info-hide-note-references)\n       (default-value 'Info-hide-note-references))\n  (save-excursion\n    (save-restriction\n      (widen) (goto-char (point-min))\n      (when (and (search-forward \"* RG:\" nil t)\n                 (search-forward\n                  \"Generated by Sphinx\"\n                  (save-excursion (search-forward \"\\x1f\" nil t)) t))\n        (set (make-local-variable 'Info-hide-note-references)\n             'hide)))))\n\n(provide 'rg-info-hack)\n\n;;; rg-info-hack.el ends here\n"
  },
  {
    "path": "rg-isearch.el",
    "content": ";;; rg-isearch.el --- rg integration into isearch -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2020 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;; This file provides rg isearch integration.\n;; Add this to your configuration to bind chosen key in isearch minibuffer:\n;;\n;; (define-key isearch-mode-map \"\\M-sr\" 'rg-isearch-menu)\n;;\n\n;; See info node `(rgel)Isearch search' for documentation or online at https://rgel.readthedocs.io/.\n\n;;; Code:\n\n(require 'rg)\n\n(defun rg-get-isearch-string ()\n  \"Extract the isearch string from the last isearch.\"\n  ;; Mimic what `isearch-occur' does.\n  (or (cond\n       ;; We can't handle arbitrary functions so just use the string.\n       ((functionp isearch-regexp-function) isearch-string)\n       ;; isearch-occur handles this as word search so insert word boundary\n       (isearch-regexp-function (concat \"\\b\" isearch-string \"\\b\"))\n       (isearch-regexp isearch-string)\n       (t isearch-string))\n      \"\"))\n\n;;;###autoload (autoload 'rg-isearch-current-file \"rg-isearch.el\" \"\" t)\n(rg-define-search rg-isearch-current-file\n  \"Run ripgrep on current file searching for latest isearch string.\"\n  :dir current\n  :query (rg-get-isearch-string)\n  :format literal\n  :files (rg-get-buffer-file-name)\n  :dir current)\n\n;;;###autoload (autoload 'rg-isearch-current-dir \"rg-isearch.el\" \"\" t)\n(rg-define-search rg-isearch-current-dir\n  \"Run ripgrep in current directory searching for latest isearch string\nin files matching the current file type.\"\n  :query (rg-get-isearch-string)\n  :format literal\n  :files current\n  :dir current)\n\n;;;###autoload (autoload 'rg-isearch-project \"rg-isearch.el\" \"\" t)\n(rg-define-search rg-isearch-project\n  \"Run ripgrep in current project searching for latest isearch string\nin files matching the current file type.\"\n  :dir project\n  :query (rg-get-isearch-string)\n  :format literal\n  :files current)\n\n;;;###autoload (autoload 'rg-isearch-menu \"rg-isearch.el\" \"\" t)\n(transient-define-prefix rg-isearch-menu ()\n  \"Show menu for rg isearch commands.\"\n  [:description \"Search with ripgrep\"\n    (3 \"f\" \"File\" rg-isearch-current-file--transient)\n    (3 \"d\" \"Dir\" rg-isearch-current-dir--transient)\n    (3 \"p\" \"Project\" rg-isearch-project--transient)])\n\n(provide 'rg-isearch)\n\n;;; rg-isearch.el ends here\n"
  },
  {
    "path": "rg-menu.el",
    "content": ";;; rg-menu.el --- Menu interface for rg -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2017 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;; Support a menu interface for rg.el based on transient.\n\n;;; Code:\n\n(require 'rg-result)\n(require 'seq)\n(require 'transient)\n(require 'cl-lib)\n\n;; Forward declarations\n(declare-function rg \"rg.el\")\n(declare-function rg-literal \"rg.el\")\n(declare-function rg-dwim \"rg.el\")\n(declare-function rg-project \"rg.el\")\n(declare-function rg-dwim-current-dir \"rg.el\")\n(declare-function rg-dwim-current-file \"rg.el\")\n(declare-function rg-list-searches \"rg.el\")\n(declare-function rg-save-search \"rg.el\")\n(declare-function rg-save-search-as-name \"rg.el\")\n(defvar rg-keymap-prefix)\n(defvar rg-command-line-flags-function)\n\n(defun rg-menu-search-initial-value ()\n  \"Provide initial value for `rg-menu' transient command.\"\n  (when (eq major-mode 'rg-mode)\n    (rg-search-flags rg-cur-search)))\n\n(eval-and-compile\n  (defun rg-menu-create-search-body (func)\n    \"Call FUNC from search menu with the flags set in the transient menu.\"\n    `((let* ((transient-flags (transient-args transient-current-command))\n             (function-flags (funcall rg-command-line-flags-function nil))\n             (rg-command-line-flags-function\n              (lambda (flags)\n                (append function-flags transient-flags flags))))\n        (call-interactively #',func))))\n\n  (defun rg-menu-create-rerun-body (func)\n    \"Call FUNC from rerun menu with flags extracted with ARGFUNC.\nIf INTERACTIVE is non nil, call func interactively, otherwise call it\nregularly.\"\n    `((let ((transient-flags (transient-args transient-current-command))\n            (current-flags (rg-search-flags rg-cur-search)))\n        (setf (rg-search-flags rg-cur-search) (seq-uniq (append current-flags transient-flags))))\n      (if (commandp #',func)\n          (call-interactively #',func)\n        (,func))))\n\n  (defun rg-menu-assemble-transient-wrapper (func body)\n    \"Create a defun with name `FUNC--transient' with BODY.\"\n    (let ((func-name (concat (symbol-name func) \"--transient\"))\n          (doc-string (format \"Transient wrapper around `%s' for `rg-menu'.\"\n                              (symbol-name func))))\n      `(progn\n         (defun ,(intern func-name) ()\n           (interactive)\n           ,@body)\n         (put ',(intern func-name) 'function-documentation\n              ;; quote to defer evalutation until func is available\n              '(concat ,doc-string \"\\n\\n\" (documentation ',func)))))))\n\n(defmacro rg-menu-wrap-transient-search (func)\n  \"Wrap FUNC with a command that apply transient arguments to the search.\nFUNC is an initial search function and not a rerun function.\"\n  (rg-menu-assemble-transient-wrapper\n   func\n   (rg-menu-create-search-body func)))\n\n(defmacro rg-menu-wrap-transient-rerun (func)\n  \"Wrap FUNC with a command that apply transient arguments to the rerun.\nFUNC is an rerun function invoked from an `rg-mode' buffer.\"\n  (rg-menu-assemble-transient-wrapper\n   func\n   (rg-menu-create-rerun-body func)))\n\n;; Regular rg entries\n(rg-menu-wrap-transient-search rg)\n(rg-menu-wrap-transient-search rg-literal)\n(rg-menu-wrap-transient-search rg-dwim)\n(rg-menu-wrap-transient-search rg-project)\n(rg-menu-wrap-transient-search rg-dwim-current-dir)\n(rg-menu-wrap-transient-search rg-dwim-current-file)\n(rg-menu-wrap-transient-search rg-list-searches)\n(rg-menu-wrap-transient-search rg-save-search)\n(rg-menu-wrap-transient-search rg-save-search-as-name)\n(rg-menu-wrap-transient-search rg-back-history)\n(rg-menu-wrap-transient-search rg-forward-history)\n\n;; Rerun rg entries\n(rg-menu-wrap-transient-rerun rg-rerun)\n(rg-menu-wrap-transient-rerun rg-rerun-change-regexp)\n(rg-menu-wrap-transient-rerun rg-rerun-change-literal)\n(rg-menu-wrap-transient-rerun rg-rerun-change-files)\n(rg-menu-wrap-transient-rerun rg-rerun-change-dir)\n\n;;;###autoload (autoload 'rg-menu \"rg-menu.el\" \"\" t)\n(transient-define-prefix rg-menu ()\n  \"Show menu buffer for rg commands.\"\n  :man-page \"rg\"\n  :value 'rg-menu-search-initial-value\n  [\"Switches\"\n   (3 \"-h\" \"Search hidden files\" \"--hidden\")\n   (6 \"-a\" \"Search binary files\" \"--text\")\n   (4 \"-z\" \"Search zipped files\" \"--search-zip\")\n   (4 \"-v\" \"Invert match\" \"--invert-match\")\n   (4 \"-U\" \"Multi line\" \"--multiline\")\n   (4 \"-.\" \"Dot all\" \"--multiline-dotall\")\n   (3 \"-w\" \"Search words\" \"--word-regexp\")\n   (5 \"-x\" \"Search lines\" \"--line-regexp\")\n   (5 \"-P\" \"Use PCRE2 regexps\" \"--pcre2\")\n   (4 \"-1\" \"Don't cross file system\" \"--one-file-system\")\n   (6 \"-L\" \"Follow symlinks\" \"--follow\")\n   (3 \"-n\" \"Override ignore files\" \"--no-ignore\")]\n  [\"Options\"\n   (3 \"-C\" \"Show context\" \"--context=\")\n   (6 \"-B\" \"Show context before\" \"--before-context=\")\n   (6 \"-A\" \"Show context after\" \"--after-context=\")\n   (4 \"-M\" \"Omit long lines\" \"--max-columns=\")\n   (4 \"-m\" \"Max matches per file\" \"--max-count=\")\n   (6 \"-s\" \"Ignore large files\" \"--max-filesize=\")\n   (4 \"-g\" \"Filter files glob\" \"--glob=\")\n   (6 \"-i\" \"Filter files glob (no case)\" \"--iglob=\")\n   (4 \"-T\" \"Exclude files types\" \"--type-not=\")\n   (5 \"-S\" \"Sort result\" \"--sort=\")\n   (5 \"-R\" \"Reverse sort result\" \"--sortr=\")\n   (6 \"-E\" \"Force encoding\" \"--encoding=\")\n   (6 \"-r\" \"Replace match\" \"--replace=\")]\n  [[:if-not-mode rg-mode\n    :description \"Search\"\n    (3 \"d\" \"Dwim project\" rg-dwim--transient)\n    (4 \"c\" \"Dwim current directory\" rg-dwim-current-dir--transient)\n    (4 \"f\" \"Dwim current file\" rg-dwim-current-file--transient)\n    (3 \"r\" \"Regex\" rg--transient)\n    (3 \"t\" \"Literal\" rg-literal--transient)\n    (3 \"p\" \"Project\" rg-project--transient)]\n   [:if-mode rg-mode\n    :description \"Rerun\"\n    (3 \"g\" \"Go\" rg-rerun--transient)\n    (3 \"r\" \"Change regex\" rg-rerun-change-regexp--transient)\n    (3 \"t\" \"Change literal\" rg-rerun-change-literal--transient)\n    (3 \"f\" \"Change files\" rg-rerun-change-files--transient)\n    (3 \"d\" \"Change directory\" rg-rerun-change-dir--transient)]\n   [:description \"Manage\"\n    (4 \"l\" \"List\" rg-list-searches--transient)\n    (4 \"s\" \"Save\" rg-save-search--transient)\n    (4 \"S\" \"Save as name\" rg-save-search-as-name--transient)]\n   [:if-mode rg-mode\n    :description \"History\"\n    (3 \"b\" \"Back\" rg-back-history--transient)\n    (3 \"w\" \"Forward\" rg-forward-history--transient)]])\n\n(eval-and-compile\n  (defun rg-menu-group-at-location-p (desc loc)\n    \"Check if group with description DESC exist at location LOC.\"\n    (let ((suffix (transient-get-suffix 'rg-menu loc)))\n      (and suffix\n           (string= (plist-get (seq-elt suffix 1) :description) desc))))\n\n  (defun rg-menu-get-loc-of-group (desc)\n    \"Find the location of the group with description DESC.\nReturns the transient location coordinates for the group or NIL if not found.\"\n    (let ((loc (list 2 0)))\n      (ignore-errors\n        (while (not (rg-menu-group-at-location-p desc loc))\n          (cl-incf (cl-second loc)))\n        loc)))\n\n  (defun rg-menu-transient-insert (group key description command)\n    \"Insert a new suffix into the rg-menu under GROUP.\nGROUP is the description of an existing group. If the group does not exist\nA new group will be created. KEY and DESCRIPTION defines the binding\nand description of the new menu entry. COMMAND is a transient wrapped\ncommand.\"\n    (unless (stringp group)\n      (user-error \"'%S' is not a string\" group))\n    (unless (or (stringp key)\n                (vectorp key))\n      (user-error \"'%S' should be a key description string or a key vector\" key))\n    (unless (stringp description)\n      (user-error \"'%S' is not a string\" description))\n    (if-let (group-loc (rg-menu-get-loc-of-group group))\n        (transient-append-suffix 'rg-menu (append group-loc '(-1))\n          (list 3 key description command))\n      (transient-append-suffix 'rg-menu '(-1 -1)\n        (vector group (list 3 key description command))))))\n\n;;;###autoload\n(defun rg-enable-menu (&optional prefix)\n  \"Bind `rg-menu' to PREFIX key.\nIf prefix is not supplied `rg-keymap-prefix' is used.\"\n  (interactive)\n  (setq prefix (or prefix rg-keymap-prefix))\n  (when prefix\n    (global-set-key prefix #'rg-menu)\n    ;; If it's already bound it might have been rebound so keep that\n    ;; instead of overriding.\n    (unless (where-is-internal #'rg-menu (list rg-mode-map) t)\n      (define-key rg-mode-map \"m\" #'rg-menu))))\n\n(provide 'rg-menu)\n\n;;; rg-menu.el ends here\n"
  },
  {
    "path": "rg-result.el",
    "content": ";;; rg-result.el ---- Result buffer implementation for rg.el. -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;;; Code:\n\n(require 'cl-lib)\n(require 'grep)\n(require 'mouse)\n(require 'rg-header)\n(require 'rg-history)\n(require 'subr-x)\n(require 'wgrep-rg)\n\n;; Forward declarations.\n(declare-function rg-build-command \"rg.el\")\n(declare-function rg-get-type-aliases \"rg.el\")\n(declare-function rg-list-searches \"rg.el\")\n(declare-function rg-read-pattern \"rg.el\")\n(declare-function rg-menu \"rg-menu.el\")\n\n\f\n;; Customizations/public vars\n(defcustom rg-use-transient-menu t\n  \"Use transient menu instead of a the global keymap.\"\n  :type 'boolean\n  :group 'rg\n  :package-version '(rg . \"2.0.0\"))\n\n(defcustom rg-show-columns nil\n  \"If t, show the columns of the matches in the output buffer.\"\n  :type 'boolean\n  :group 'rg)\n\n(defcustom rg-group-result t\n  \"Group matches in the same file together.\nIf nil, the file name is repeated at the beginning of every match line.\"\n  :type 'boolean\n  :group 'rg\n  :package-version '(rg . \"2.0.0\"))\n\n(defcustom rg-show-header t\n  \"Show header in results buffer if non nil.\"\n  :type 'boolean\n  :group 'rg)\n\n(defcustom rg-hide-command t\n  \"Hide most of rg command line when non nil.\"\n  :type 'boolean\n  :group 'rg)\n\n(defcustom rg-align-position-numbers t\n  \"If non nil, alignment of line and column numbers is turned on.\"\n  :type 'boolean\n  :group 'rg\n  :package-version '(rg . \"2.0.0\"))\n\n(defcustom rg-align-line-number-field-length 4\n  \"Field length of aligned line numbers.\"\n  :type 'integer\n  :group 'rg)\n\n(defcustom rg-align-column-number-field-length 3\n  \"Field length of aligned column numbers.\"\n  :type 'integer\n  :group 'rg)\n\n(defcustom rg-align-line-column-separator \" \"\n  \"Separator used between line and column numbers.\nDepends on `rg-show-columns'.  Default is ':'.\"\n  :type 'string\n  :group 'rg\n  :package-version '(rg . \"2.0.0\"))\n\n(defcustom rg-align-position-content-separator \" \"\n  \"Separator used between position numbers and the matching file content.\nDefault is ':'.\"\n  :type 'string\n  :group 'rg\n  :package-version '(rg . \"2.0.0\"))\n\n(defvar rg-filter-hook nil\n  \"Hook for new content in the rg buffer.\nThis hook is called every time the rg buffer has been updated with\nnew content and filtered through the `rg-filter' function.\")\n\n\f\n;; Faces\n(defgroup rg-face nil\n  \"Settings for rg faces.\"\n  :group 'rg)\n\n(defface rg-match-face\n  `((t :inherit ,grep-match-face))\n  \"Face for match highlight.\"\n  :group 'rg-face)\n\n(defface rg-error-face\n  `((t :inherit ,grep-error-face))\n  \"Face for error.\"\n  :group 'rg-face)\n\n(defface rg-context-face\n  `((t :inherit ,grep-context-face))\n  \"Face for context lines.\"\n  :group 'rg-face)\n\n(defface rg-info-face\n  '((t :inherit compilation-info))\n  \"Face for info.\"\n  :group 'rg-face)\n\n(defface rg-warning-face\n  '((t :inherit compilation-warning))\n  \"Face for warning.\"\n  :group 'rg-face)\n\n(defface rg-filename-face\n  '((t :inherit rg-info-face))\n  \"Face for filename.\"\n  :group 'rg-face)\n\n(defface rg-file-tag-face\n  '((t :inherit rg-info-face))\n  \"Face for file tag in grouped layout.\"\n  :group 'rg-face)\n\n(defface rg-line-number-face\n  '((t :inherit compilation-line-number))\n  \"Face for line numbers.\"\n  :group 'rg-face)\n\n(defface rg-column-number-face\n  '((t :inherit compilation-column-number))\n  \"Face for column numbers.\"\n  :group 'rg-face)\n\n(defface rg-match-position-face\n  '((t :inherit default))\n  \"Face that is being appended to file positions.\nThis is the start of each matching line. This includes line number\nand, depending on configuration, column number and file name.\"\n  :group 'rg-face)\n\n\f\n;; Internal vars and structs\n\n(cl-defstruct (rg-search (:constructor rg-search-create)\n                         (:constructor rg-search-new (pattern files dir))\n                         (:copier rg-search-copy))\n  pattern                ; search pattern\n  files                  ; files to search\n  dir                    ; base directory\n  full-command           ; full-command (t or nil)\n  literal                ; literal patterh (t or nil)\n  flags)                 ; search specific flags\n\n(defvar-local rg-cur-search nil\n  \"Stores parameters of last search.\nBecomes buffer local in `rg-mode' buffers.\")\n(put 'rg-cur-search 'permanent-local t)\n\n(defvar-local rg-search-history nil\n  \"Stores the search history per rg-mode buffer.\")\n(put 'rg-search-history 'permanent-local t)\n\n(defvar-local rg-hit-count 0\n  \"Stores number of hits in a search.\")\n\n(defvar-local rg-match-positions nil\n  \"Stores position of matches in a search.\nEach element is consists by (match-beginning-marker . match-string-length).\")\n\n(defvar-local rg-recompile nil\n  \"Is `recompile' in progress or `compile-start'.\")\n\n(defconst rg-mode-font-lock-keywords\n  '(;; Command output lines.\n    (\": \\\\(.+\\\\): \\\\(?:Permission denied\\\\|No such \\\\(?:file or directory\\\\|device or address\\\\)\\\\)$\"\n     1 'rg-error-face)\n    (\"^rg[/a-zA-z]* started.*\"\n     (0 '(face nil compilation-message nil help-echo nil mouse-face nil) t))\n    (\"^rg[/a-zA-z]* finished \\\\(?:(\\\\([0-9]+ matches found\\\\))\\\\|with \\\\(no matches found\\\\)\\\\).*\"\n     (0 '(face nil compilation-message nil help-echo nil mouse-face nil) t)\n     (1 'rg-info-face nil t)\n     (2 'rg-warning-face nil t))\n    (\"^rg[/a-zA-z]* \\\\(exited abnormally\\\\|interrupt\\\\|killed\\\\|terminated\\\\)\\\\(?:.*with code \\\\([0-9]+\\\\)\\\\)?.*\"\n     (0 '(face nil compilation-message nil help-echo nil mouse-face nil) t)\n     (1 'rg-error-face)\n     (2 'rg-error-face nil t))\n    ;; \"filename-linenumber-\" or \"linenumber-\" format is used for\n    ;; context lines in rg\n    (\"^ *\\\\(?:.+?-\\\\)?[0-9]+-.*\\n\" (0 'rg-context-face))\n    (\"^.*rg \\\\(--color=always .*$\\\\)\"\n     (0 rg-command-line-properties)\n     (1 (rg-hidden-command-line-properties)))\n    (\"^-\\\\*- mode: rg; default-directory: \\\"\\\\(.*\\\\)\\\" -\\\\*-$\"\n     (1 rg-directory-properties))\n    (\"\\\\[\\\\.\\\\.\\\\. [0-9]+ more match\\\\(es\\\\)*\\\\]$\"\n     (0 'rg-info-face nil t))))\n\n(defvar rg-menu-map\n  (let ((map (make-sparse-keymap \"RipGrep\")))\n    (define-key map [rg-toggle-command-hiding]\n      '(menu-item \"Toggle command visibility\"\n                  rg-toggle-command-hiding\n                  :help \"Toggle showing verbose command options\"))\n    (define-key map [rg-enable-wgrep]\n      '(menu-item \"Edit buffer\" wgrep-change-to-wgrep-mode\n                  :help \"Edit buffer and save changes.\"))\n    (define-key map [rg-save-search]\n      '(menu-item \"Save search\" rg-save-search-as-name\n                  :help \"Save current search.\"))\n    (define-key map [rg-search-list]\n      '(menu-item \"List searches\" rg-list-searches\n                  :help \"List all ripgrep search buffers.\"))\n    (define-key map [rg-change-dir]\n      '(menu-item \"Change dir\" rg-rerun-change-dir\n                  :help \"Rerun search in another directory.\"))\n    (define-key map [rg-change-files]\n      '(menu-item \"Change file type\" rg-rerun-change-files\n                  :help \"Rerun search on other file types.\"))\n    (define-key map [rg-change-regexp]\n      '(menu-item \"Change regexp\" rg-rerun-change-regexp\n                  :help \"Run regexp search with changed pattern.\"))\n    (define-key map [rg-change-literal]\n      '(menu-item \"Change literal\" rg-rerun-change-literal\n                  :help \"Run literal search with changed search string.\"))\n    (define-key map [rg-kill-compilation]\n      '(menu-item \"Kill Ripgrep\" kill-compilation\n\t\t  :help \"Kill the currently running rg process\"))\n    (define-key map [rg-another]\n      '(menu-item \"Another search...\"\n                  (lambda ()\n                    (interactive)\n                    (rg-save-search)\n                    (call-interactively 'rg))\n\t\t  :help \"Save current search results and start a new search.\"))\n    (define-key map [rg-recompile]\n      '(menu-item \"Go...\" rg-recompile\n\t\t  :help \"Rerun search\"))\n    map))\n\n(defvar rg-mode-map\n  (let ((map (make-sparse-keymap)))\n    (set-keymap-parent map compilation-minor-mode-map)\n    (define-key map \" \" 'scroll-up-command)\n    (define-key map [?\\S-\\ ] 'scroll-down-command)\n    (define-key map \"\\^?\" 'scroll-down-command)\n    (define-key map \"\\C-c\\C-f\" 'next-error-follow-minor-mode)\n    (define-key map \"\\r\" 'compile-goto-error)  ;; ?\n    (define-key map \"n\" 'next-error-no-select)\n    (define-key map \"p\" 'previous-error-no-select)\n    (define-key map \"{\" 'compilation-previous-file)\n    (define-key map \"}\" 'compilation-next-file)\n    (define-key map \"\\t\" 'compilation-next-error)\n    (define-key map [backtab] 'compilation-previous-error)\n\n    (define-key map \"c\" 'rg-rerun-toggle-case)\n    (define-key map \"d\" 'rg-rerun-change-dir)\n    (define-key map \"f\" 'rg-rerun-change-files)\n    (define-key map \"g\" 'rg-recompile)\n    (define-key map \"i\" 'rg-rerun-toggle-ignore)\n    (define-key map \"L\" 'rg-list-searches)\n    (define-key map \"r\" 'rg-rerun-change-regexp)\n    (define-key map \"s\" 'rg-save-search)\n    (define-key map \"S\" 'rg-save-search-as-name)\n    (define-key map \"t\" 'rg-rerun-change-literal)\n    (define-key map \"e\" 'wgrep-change-to-wgrep-mode)\n    (define-key map \"\\M-N\" 'rg-next-file)\n    (define-key map \"\\M-P\" 'rg-prev-file)\n    (define-key map \"\\C-c>\" 'rg-forward-history)\n    (define-key map \"\\C-c<\" 'rg-back-history)\n    (when rg-use-transient-menu\n      (define-key map \"m\" #'rg-menu))\n\n    ;; Set up the menu-bar\n    (define-key map [menu-bar rg]\n      (cons \"RipGrep\" rg-menu-map))\n    map)\n  \"The keymap for `rg-mode'.\")\n\n(defvar rg-ellipsis (if (char-displayable-p ?…) \"[…]\" \"[...]\")\n  \"Used when hiding command line.\")\n\n(defvar rg-finish-functions '()\n  \"Functions to call when a ripgrep process finishes.\n\nEach function is called with two arguments: the compilation buffer,\nand a string describing how the process finished.\")\n\n\f\n;; Defuns\n\n(defun rg-create-mouse-map (command)\n  \"Create a mouse-map for the COMMAND.\nThis makes sure point moves to click and that the clicked window is\nselected.\"\n  (let ((map (make-sparse-keymap)))\n    (define-key map [down-mouse-2] 'mouse-set-point)\n    (define-key map [mouse-2] command)\n    (define-key map \"\\C-m\" command)\n    map))\n\n;; This solution was mostly copied from emacs grep.el and adjusted to\n;; be more usable.\n(defvar rg-command-line-properties\n  (let ((map (rg-create-mouse-map 'rg-toggle-command-hiding)))\n    `(face rg-context-face mouse-face highlight\n           help-echo \"RET, mouse-2: show unabbreviated command\"\n           keymap ,map))\n  \"Properties for graying out and keymap for hiding command line.\")\n\n(defun rg-hidden-command-line-properties ()\n  \"Return properties of button-like ellipsis on part of rg command line.\"\n  (append\n   '(face nil rg-command-hidden-part t)\n   (when rg-hide-command\n     `(display ,rg-ellipsis))))\n\n(defun rg-toggle-command-hiding ()\n  \"Toggle showing the hidden part of rg command line.\"\n  (interactive)\n  (with-silent-modifications\n    (let* ((beg (next-single-property-change (point-min) 'rg-command-hidden-part))\n           (end (when beg\n                  (next-single-property-change beg 'rg-command-hidden-part))))\n      (if end\n          (if (get-text-property beg 'display)\n              (remove-list-of-text-properties beg end '(display))\n            (add-text-properties beg end `(display ,rg-ellipsis)))\n        (user-error \"No abbreviated part to hide/show\")))))\n\n(defvar rg-directory-properties\n  (let ((map (rg-create-mouse-map 'rg-rerun-change-dir)))\n    `(face rg-filename-face mouse-face highlight\n           help-echo \"RET, mouse-2: Change search directory\"\n           keymap ,map))\n  \"Properties for `default-directory' in header.\")\n\n(defun rg-list-toggle (elem list)\n  \"Remove ELEM from LIST if present or add it if not present.\nReturns the new list.\"\n  (if (member elem list)\n      (delete elem list)\n    (push elem list)))\n\n(defun rg-process-setup ()\n  \"Setup compilation variables and buffer for `rg'.\nSet up `compilation-exit-message-function'.\"\n  (set (make-local-variable 'compilation-exit-message-function)\n       (lambda (status code msg)\n         (if (eq status 'exit)\n             ;; This relies on the fact that `compilation-start'\n             ;; sets buffer-modified to nil before running the command,\n             ;; so the buffer is still unmodified if there is no output.\n             (cond ((and (zerop code) (buffer-modified-p))\n                    `(,(format \"finished (%d matches found)\\n\" rg-hit-count) . \"matched\"))\n                   ((not (buffer-modified-p))\n                    '(\"finished with no matches found\\n\" . \"no match\"))\n                   (t\n                    (cons msg code)))\n           (cons msg code)))))\n\n(defun rg-prepend-space (text length)\n  \"Prepend TEXT with LENGTH number of spaces.\"\n  (let ((space-count (- length (length text))))\n    (concat\n     (when (> space-count 0) (make-string space-count ?\\s))\n     text)))\n\n(defun rg-perform-position-numbers-alignment (line-number &optional column-number context-marker )\n  \"Return aligned LINE-NUMBER, COLUMN-NUMBER and CONTEXT-MARKER.\"\n  (let* ((line-col-separator (or rg-align-line-column-separator \":\"))\n         (pos-content-separator (or rg-align-position-content-separator \":\"))\n         (pos-content-separator (if rg-show-columns\n                                    pos-content-separator\n                                  (propertize pos-content-separator 'invisible t)))\n         (line-number-width\n          (if (and rg-show-columns context-marker)\n              ;; Context lines should be aligned to column numbers\n              (+ rg-align-line-number-field-length\n                 (1+ rg-align-column-number-field-length))\n            rg-align-line-number-field-length))\n         (column-number (when column-number\n                          (if rg-show-columns\n                              column-number\n                            (propertize column-number 'invisible t)))))\n    (cl-assert (if column-number (not context-marker) context-marker))\n    (concat (rg-prepend-space line-number line-number-width)\n            (if column-number\n                (concat (if rg-show-columns\n                            line-col-separator\n                          pos-content-separator)\n                        (rg-prepend-space column-number\n                                          rg-align-column-number-field-length)\n                        pos-content-separator)\n              context-marker))))\n\n(defun rg-format-line-and-column-numbers (beg end)\n  \"Align numbers in region defined by BEG and END.\"\n  (goto-char beg)\n  (while (re-search-forward\n          \"^\\033\\\\[[0]*m\\033\\\\[32m\\\\([0-9]*?\\\\)\\033\\\\[[0]*m\\\\(:\\\\|-\\\\)\\\\(?:\\033\\\\[[0]*m\\\\([0-9]*?\\\\)\\033\\\\[[0]*m:\\\\)?\"\n          end 1)\n    (let* ((line-match (match-string 1))\n           (col-separator-match (match-string 2))\n           (context-marker (when (equal col-separator-match \"-\")\n                             col-separator-match))\n           (column-match (match-string 3)))\n    (cond\n     (rg-align-position-numbers\n      (replace-match\n       (rg-perform-position-numbers-alignment\n        line-match column-match context-marker)\n       t t))\n     ((and column-match (not rg-show-columns))\n      (replace-match\n       (propertize col-separator-match 'invisible t) t t nil 2)\n      (replace-match (propertize column-match 'invisible t) t t nil 3))))))\n\n(defun rg-filter ()\n  \"Handle match highlighting escape sequences inserted by the rg process.\nThis function is called from `compilation-filter-hook'.\"\n  (save-excursion\n    (forward-line 0)\n    (let ((end (point)) beg temp-positions)\n      (goto-char compilation-filter-start)\n      (forward-line 0)\n      (setq beg (point))\n      (when (zerop rg-hit-count)\n        (newline))\n      ;; Only operate on whole lines so we don't get caught with part of an\n      ;; escape sequence in one chunk and the rest in another.\n      (when (< (point) end)\n        (setq end (copy-marker end))\n        ;; Add File: in front of filename\n        (when rg-group-result\n          (while (re-search-forward \"^\\033\\\\[[0]*m\\033\\\\[35m\\\\(.*?\\\\)\\033\\\\[[0]*m$\" end 1)\n            (replace-match (concat (propertize \"File:\"\n                                               'rg-file-message t\n                                               'face nil\n                                               'font-lock-face 'rg-file-tag-face)\n                                   \" \"\n                                   (propertize (match-string 1)\n                                               'face nil\n                                               'font-lock-face 'rg-filename-face))\n                           t t))\n          (goto-char beg))\n\n        ;; Highlight rg matches and delete marking sequences.\n        (while (re-search-forward \"\\033\\\\[[0]*m\\033\\\\[[3]*1m\\033\\\\[[3]*1m\\\\(.*?\\\\)\\033\\\\[[0]*m\" end 1)\n          (replace-match (propertize (match-string 1)\n                                     'face nil 'font-lock-face 'rg-match-face)\n                         t t)\n          (push (cons (copy-marker (match-beginning 0))\n                      (length (match-string 0)))\n                temp-positions)\n          (cl-incf rg-hit-count))\n        (rg-format-line-and-column-numbers beg end)\n\n        ;; Delete all remaining escape sequences\n        (goto-char beg)\n        (while (re-search-forward \"\\033\\\\[[0-9;]*[0mK]\" end 1)\n          (replace-match \"\" t t))\n\n        (goto-char beg)\n\n        (setq rg-match-positions (nconc rg-match-positions (nreverse temp-positions)))\n\n        (run-hooks 'rg-filter-hook)))))\n\n;; The regexp and filter functions below were taken from ag.el\n;; Kudos to the people from https://github.com/Wilfred/ag.el for these.\n(defconst rg-file-line-column-pattern-nogroup\n  \"^\\\\([^\\n:]+?\\\\):\\\\([1-9][0-9]*\\\\):\\\\([1-9][0-9]*\\\\):\"\n  \"A regexp pattern that groups output.\nGroups into filename,line number and column number.\")\n\n(defun rg-file-line-column-pattern-group ()\n  \"A regexp pattern to match line number and column number with grouped output.\"\n  (concat \"^ *\\\\([1-9][0-9]*\\\\)\"\n          (regexp-quote (or (and rg-align-position-numbers\n                                 rg-align-line-column-separator) \":\"))\n          \" *\\\\([1-9][0-9]*\\\\)\"\n          (regexp-quote (or (and rg-align-position-numbers\n                                 rg-align-position-content-separator) \":\"))))\n\n(defconst rg-file-line-pattern-nogroup\n  \"^\\\\([^\\n:]+?\\\\):\\\\([1-9][0-9]*\\\\):\"\n  \"A regexp pattern that groups output into filename, line number.\")\n\n(defun rg-file-line-pattern-group ()\n  \"A regexp pattern to match line number with grouped output.\"\n  (concat \"^ *\\\\([1-9][0-9]*\\\\)\"\n          (regexp-quote (or (and rg-align-position-numbers\n                                 rg-align-position-content-separator) \":\"))))\n\n(defun rg-match-grouped-filename ()\n  \"Match filename backwards when a line/column match is found.\"\n  (save-match-data\n    (save-excursion\n      (when (re-search-backward \"^File: \\\\(.*\\\\)$\" (point-min) t)\n        (list (match-string 1))))))\n\n(defun rg-set-compilation-error-regexps ()\n  \"Set the compilation mode regexps for errors for rg-mode buffers.\"\n  (set (make-local-variable 'compilation-error-regexp-alist)\n       '(rg-group-with-column\n         rg-nogroup-with-column\n         rg-group-no-column\n         rg-nogroup-no-column))\n  (set (make-local-variable 'compilation-error-regexp-alist-alist)\n       (list (cons 'rg-nogroup-no-column (list rg-file-line-pattern-nogroup 1 2))\n             (cons 'rg-nogroup-with-column (list rg-file-line-column-pattern-nogroup 1 2 3))\n             (cons 'rg-group-with-column (list (rg-file-line-column-pattern-group) 'rg-match-grouped-filename 1 2))\n             (cons 'rg-group-no-column (list (rg-file-line-pattern-group) 'rg-match-grouped-filename 1)))))\n\n(define-compilation-mode rg-mode \"rg\"\n  \"Major mode for `rg' search results.\nCommands:\n\\\\<rg-mode-map>\n\\\\[rg-rerun-change-dir]\\t Repeat this search in another directory (`rg-rerun-change-dir').\n\\\\[rg-rerun-change-files]\\t Repeat this search with another file pattern (`rg-rerun-change-files').\n\\\\[rg-rerun-change-regexp]\\t Change the search regexp for the current search (`rg-rerun-change-regexp').\n\\\\[rg-rerun-change-literal]\\t Change the search literal for the current search (`rg-rerun-change-literal').\n\\\\[rg-rerun-toggle-ignore]\\t Repeat search with toggled '--no-ignore' flag (`rg-rerun-toggle-ignore').\n\\\\[rg-rerun-toggle-case]\\t Repeat search with toggled case insensitive setting (`rg-rerun-toggle-case').\n\\\\[rg-save-search-as-name]\\t Save search result, prompt for new name (`rg-save-search-as-name').\n\\\\[rg-save-search]\\t Save search result to some unique name (`rg-save-search').\n\\\\[wgrep-change-to-wgrep-mode]\\t Change mode to `wgrep'.\n\n\\\\{rg-mode-map}\"\n  (set (make-local-variable 'tool-bar-map) grep-mode-tool-bar-map)\n  (set (make-local-variable 'compilation-error-face) 'rg-filename-face)\n  (set (make-local-variable 'compilation-message-face) 'rg-match-position-face)\n  (set (make-local-variable 'compilation-line-face) 'rg-line-number-face)\n  (set (make-local-variable 'compilation-column-face) 'rg-column-number-face)\n\n  ;; compilation-directory-matcher can't be nil, so we set it to a regexp that\n  ;; can never match.\n  (set (make-local-variable 'compilation-directory-matcher) '(\"\\\\`a\\\\`\"))\n  (set (make-local-variable 'compilation-process-setup-function)\n       'rg-process-setup)\n  (set (make-local-variable 'compilation-disable-input) t)\n  (set (make-local-variable 'compilation-error-screen-columns) nil)\n  (unless rg-search-history\n    (setq rg-search-history (rg-history-create)))\n  (set (make-local-variable 'compilation-filter-hook) '(rg-filter))\n  ;; Set compilation error regexps as the last compilation-mode-hook to be\n  ;; able to override these if they were set by other hooks.\n  (add-hook 'compilation-mode-hook\n            'rg-set-compilation-error-regexps 90 'local))\n\n(defun rg-maybe-show-header ()\n  \"Recreate header if enabled.\"\n  (when rg-show-header\n    (rg-create-header-line 'rg-cur-search\n                           (rg-search-full-command rg-cur-search))))\n\n(defun rg-mode-init (search)\n  \"Initiate `rg-mode' with SEARCH in current buffer.\"\n  (unless (eq major-mode 'rg-mode)\n    (error \"Function rg-mode-init called in non rg mode buffer\"))\n  (hack-dir-local-variables-non-file-buffer)\n  (setq rg-cur-search search)\n  (rg-history-push (rg-search-copy rg-cur-search)\n                   rg-search-history)\n  (rg-maybe-show-header)\n  (rg-configure-imenu))\n\n(defun rg-recompile ()\n  \"Rerun the current search.\"\n  (interactive)\n  (let ((rg-recompile t))\n    (recompile))\n  (hack-dir-local-variables-non-file-buffer)\n  (rg-maybe-show-header)\n  (rg-configure-imenu))\n\n(defun rg-rerun (&optional no-history)\n  \"Run `recompile' with `compilation-arguments' taken from `rg-cur-search'.\nIf NO-HISTORY is non nil skip adding the search to the search history.\"\n  (let ((pattern (rg-search-pattern rg-cur-search))\n        (files (rg-search-files rg-cur-search))\n        (dir (rg-search-dir rg-cur-search))\n        (literal (rg-search-literal rg-cur-search))\n        (flags (rg-search-flags rg-cur-search)))\n    ;; compilation-directory is used as search dir and\n    ;; default-directory is used as the base for file paths.\n    (setq compilation-directory dir)\n    (setq default-directory compilation-directory)\n    (setcar compilation-arguments\n            (or (rg-search-full-command rg-cur-search)\n                (rg-build-command pattern files literal flags)))\n    (unless no-history\n      (rg-history-push (rg-search-copy rg-cur-search)\n                       rg-search-history))\n    (rg-recompile)))\n\n(defun rg-navigate-file-message (pos limit direction)\n  \"Return position of next 'rg-file-message text property.\nPOS is the start position of the search and LIMIT is the limit of the\nsearch.  If the property is not found within LIMIT, LIMIT is returned.  If\nDIRECTION is positive search forward in the buffer, otherwise search\nbackward.\"\n  (let ((prop-change-func\n         (if (> direction 0)\n             'next-single-property-change\n           'previous-single-property-change)))\n    (while\n        (progn\n          (setq pos (funcall prop-change-func pos 'rg-file-message nil limit))\n          (and (not (eq pos limit))\n               (not (get-text-property pos 'rg-file-message)))))\n    pos))\n\n(defun rg-navigate-file-group (steps)\n  \"Move point to the a matched result group in the compilation buffer.\nSTEPS decides how many groups to move past.  Negative value means\nbackwards and positive means forwards.\"\n  (let (move-to\n        (pos (point))\n        (steps-left (abs steps))\n        (limit\n         (if (< steps 0)\n             (point-min)\n           (point-max))))\n    (while  (and (> steps-left 0) (not (equal pos limit)))\n      (setq pos (rg-navigate-file-message pos limit steps))\n      (unless (eq pos limit)\n        (setq move-to pos))\n      (setq steps-left (- steps-left 1)))\n    (when move-to\n      (goto-char move-to))))\n\n(defun rg-rerun-toggle-flag (flag)\n  \"Toggle FLAG in `rg-cur-search`.\"\n  (setf (rg-search-flags rg-cur-search)\n        (rg-list-toggle flag (rg-search-flags rg-cur-search)))\n  (rg-rerun))\n\n(defun rg-rerun-toggle-case ()\n  \"Rerun last search with toggled case sensitivity setting.\"\n  (interactive)\n  (rg-rerun-toggle-flag \"-i\"))\n\n(defun rg-rerun-toggle-ignore ()\n  \"Rerun last search with toggled '--no-ignore' flag.\"\n  (interactive)\n  (rg-rerun-toggle-flag \"--no-ignore\"))\n\n(defun rg-rerun-toggle-rexexp-literal ()\n  \"Switch between literal and regexp and rerun last search.\"\n  (interactive)\n  (setf (rg-search-literal rg-cur-search)\n        (not (rg-search-literal rg-cur-search)))\n  (rg-rerun))\n\n(defun rg-rerun-change-query ()\n  \"Rerun last search and change search string.\"\n  (interactive)\n  (rg-rerun-change-search-string\n   (rg-search-literal rg-cur-search)))\n\n(defun rg-rerun-change-search-string (literal)\n  \"Rerun last search but prompt for new search pattern.\nIF LITERAL is non nil this will trigger a literal search,\notherwise a regexp search.\"\n  (let ((pattern (rg-search-pattern rg-cur-search))\n        (read-from-minibuffer-orig (symbol-function 'read-from-minibuffer)))\n    ;; Override read-from-minibuffer in order to insert the original\n    ;; pattern in the input area.\n    (cl-letf (((symbol-function #'read-from-minibuffer)\n               (lambda (prompt &optional _ &rest args)\n                 (apply read-from-minibuffer-orig prompt pattern args))))\n      (setf (rg-search-pattern rg-cur-search) (rg-read-pattern literal pattern)))\n    (setf (rg-search-literal rg-cur-search) literal)\n    (rg-rerun)))\n\n(defun rg-rerun-change-regexp ()\n  \"Rerun last search but prompt for new regexp.\"\n  (interactive)\n  (rg-rerun-change-search-string nil))\n\n(defun rg-rerun-change-literal ()\n  \"Rerun last search but prompt for new literal.\"\n  (interactive)\n  (rg-rerun-change-search-string t))\n\n(defun rg-rerun-change-files()\n  \"Rerun last search but prompt for new files.\"\n  (interactive)\n  (let ((files (rg-search-files rg-cur-search)))\n    (setf (rg-search-files rg-cur-search)\n          (completing-read\n           (concat \"Repeat search in files (default: [\" files \"]): \")\n           (rg-get-type-aliases)\n           nil nil nil 'rg-files-history\n           files))\n    (rg-rerun)))\n\n(defun rg-rerun-change-dir()\n  \"Rerun last search but prompt for new dir.\"\n  (interactive)\n  (setf (rg-search-dir rg-cur-search)\n        (read-directory-name \"In directory: \"\n                             (rg-search-dir rg-cur-search) nil))\n  (rg-rerun))\n\n(defun rg-next-file (n)\n  \"Move point to next file's first match.\nPrefix arg N decides how many files to navigate.  When\n`rg-group-result' is nil this is the same as invoking\n`compilation-next-file', otherwise this will navigate to the\nnext file with grouped matches.\"\n  (interactive \"p\")\n  (if rg-group-result\n      (when (rg-navigate-file-group n)\n        (forward-line))\n    (compilation-next-file n)))\n\n(defun rg-prev-file (n)\n  \"Move point to previous file's first match.\nPrefix arg N decides how many files to navigate.  When\n`rg-group-result' is nil this is the same as invoking\n`compilation-previous-file', otherwise this will navigate to the\nprevious file with grouped matches.\"\n  (interactive \"p\")\n  (if rg-group-result\n      (let ((steps\n             ;; On match rows we move 2 steps back to get to previous\n             ;; file, otherwise 1 step.  The later is on file\n             ;; headings, space between files and at the end of search results.\n             (if (or (get-text-property (point) 'rg-file-message)\n                     (save-excursion\n                       (beginning-of-line)\n                       (looking-at \"^\\\\(?:rg finished .*\\\\)*$\")))\n                 n\n               (+ n 1))))\n        (when (rg-navigate-file-group (- steps))\n          (forward-line)))\n    (compilation-previous-file n)))\n\n(defun rg-back-history ()\n  \"Navigate back in the search history.\"\n  (interactive)\n  (if-let (prev (rg-history-back rg-search-history))\n      (progn\n        (setq rg-cur-search (rg-search-copy prev))\n        (rg-rerun 'no-history))\n    (message \"No more history elements for back.\")))\n\n(defun rg-forward-history ()\n  \"Navigate forward in the search history.\"\n  (interactive)\n  (if-let (next (rg-history-forward rg-search-history))\n      (progn\n        (setq rg-cur-search (rg-search-copy next))\n        (rg-rerun 'no-history))\n    (message \"No more history elements for forward.\")))\n\n(defun rg-configure-imenu ()\n  \"Add files with matches to imenu if rg-group-result is enabled.\"\n  (when rg-group-result\n    (setq imenu-create-index-function\n          (lambda ()\n            (goto-char (point-min))\n            (let ((elements nil)\n                  (filepath nil)\n                  (nextfile (point-min)))\n              (while (setq nextfile (rg-navigate-file-message nextfile nil 1))\n                (save-excursion\n                  (goto-char nextfile)\n                  (and (looking-at-p \"^File: \") (forward-char 6))\n                  (setq filepath (buffer-substring-no-properties (point) (line-end-position))))\n                (push (cons filepath nextfile) elements))\n              (nreverse elements))))))\n\n(defun rg-cur-search-pattern ()\n  \"Get the current search pattern.\"\n  (rg-search-pattern rg-cur-search))\n\n(provide 'rg-result)\n\n;; Local Variables:\n;; byte-compile-warnings: (not docstrings)\n;; End:\n\n;;; rg-result.el ends here\n"
  },
  {
    "path": "rg.el",
    "content": ";;; rg.el --- A search tool based on ripgrep -*- lexical-binding: t; -*-\n\n;; Copyright (C) 1985-1987, 1993-1999, 2001-2015 Free Software\n;; Foundation, Inc.\n;; Copyright (C) 2016-2018 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;;         Roland McGrath <roland@gnu.org>\n;; Version: 2.4.1\n;; URL: https://github.com/dajva/rg.el\n;; Package-Requires: ((emacs \"28.1\") (transient \"0.9.2\") (wgrep \"2.1.10\"))\n;; Keywords: matching, tools\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;; A search package based on the ripgrep command line tool.\n;; It allows you to interactively create searches, doing automatic\n;; searches based on the editing context, refining and modifying\n;; search results and much more.  It is also highly configurable to be\n;; able to fit different users' needs.\n\n;; If you are used to built-in Emacs rgrep command, transitioning to\n;; rg should be simple.  rg provides a lot of extra features\n;; but the basics are similar.\n;;\n;; The big benefit of using ripgrep instead of grep as a backend is\n;; speed.  Especially when searching large source code repositories\n;; where ripgrep really shines.\n\n;; See info node `(rgel)Top' for documentation or online at https://rgel.readthedocs.io.\n\n\n;;; Code:\n\n(require 'cl-lib)\n(require 'cus-edit)\n(require 'grep)\n(require 'rg-ibuffer)\n(require 'rg-menu)\n(require 'rg-result)\n(require 'rg-info-hack)\n(require 'subr-x)\n(require 'vc)\n(require 'files-x)\n\n\f\n;; Customizations/public vars\n(defgroup rg nil\n  \"Settings for rg.\"\n  :group 'tools\n  :group 'external)\n\n(defcustom rg-custom-type-aliases\n  '()\n  \"A list of file type aliases that are added to the ripgrep built in aliases.\nEach list element may be a (string . string) cons containing the name of the\ntype alias and the file patterns, or a lambda returning a similar cons cell.\nA lambda should return nil if it currently has no type aliases to contribute.\"\n  :type '(repeat (choice (cons string string) function))\n  :group 'rg)\n\n(defcustom rg-prioritized-type-aliases '()\n  \"A list of file type aliases that are prioritized.\nWhen detecting the file type from the current buffer these aliases are selected\nif there are conflicting aliases for a file type.  Contains only the alias names\nand need to match alias names of ripgrep's built in aliases.  The order of the\nlist decides the priority among the types in the list.\"\n  :type '(repeat string)\n  :group 'rg)\n\n(defcustom rg-executable (executable-find \"rg\")\n  \"Ripgrep executable.\"\n  :type 'string\n  :group 'rg)\n\n(defcustom rg-executable-per-connection t\n  \"Invoke `executable-find' per host and store as connection local variable.\nOnly works in Emacs 27.1 or later.\"\n  :type 'boolean\n  :group 'rg)\n\n(defcustom rg-command-line-flags nil\n  \"List of command line flags for rg.\nAlternatively a function returning a list of flags.\"\n  :type '(choice function (repeat string))\n  :group 'rg)\n\n(defcustom rg-ignore-case 'case-fold-search\n  \"Decides which mode of case insensitive search that is enabled.\nCASE-FOLD-SEARCH means that the variable `case-fold-search' will\ntrigger smart-case functionality if non nil.\nSMART means that case insensitive search will be triggered if the\nsearch pattern contains only lower case.  If the pattern contains upper\ncase letters, case sensitive search will be performed.  This is similar\nto the rg '--smart-case' flag.\nFORCE will force case insensitive search regardless of the content of\nthe search pattern.\nNIL means case sensitive search will be forced.\"\n  :type '(choice (const :tag \"Case Fold Search\" case-fold-search)\n                 (const :tag \"Smart\" smart)\n                 (const :tag \"Force\" force)\n                 (const :tag \"Off\" nil))\n  :group 'rg)\n\n;;;###autoload\n(defcustom rg-keymap-prefix \"\\C-cs\"\n  \"Prefix for global `rg' keymap.\"\n  :type 'key-sequence\n  :group 'rg)\n\n(defcustom rg-default-alias-fallback \"everything\"\n  \"The default file alias to use when no alias can be determined.\nThis must be a string that can be match against the types returned\nfrom `rg-get-type-aliases'.\"\n  :type 'string\n  :group 'rg)\n\n(defcustom rg-buffer-name \"rg\"\n  \"Search results buffer name.\nCan be string or function.\"\n  :type '(choice string function)\n  :group 'rg)\n\n(defcustom rg-ignore-ripgreprc t\n  \"Ignore the ripgrep config file.\nDisabling this setting can break functionality of this package.\"\n  :type 'boolean\n  :group 'rg)\n\n(defcustom rg-w32-unicode nil\n  \"Enable Unicode support on Windows.\nA workaround for NTEmacs subprocess not supporting Unicode arguments.\"\n  :type 'boolean\n  :group 'rg)\n\n(defcustom rg-w32-ripgrep-proxy\n  (expand-file-name \"rg-w32-ripgrep-proxy.bat\" user-emacs-directory)\n  \"An automatically generated temporary batch file.\nUsed to proxy ripgrep Unicode arguments.\"\n  :type 'string\n  :group 'rg)\n\n;;;###autoload\n(defvar rg-command-line-flags-function 'identity\n  \"Function to modify command line flags of a search.\nThe argument of the function is an optional list of search specific\ncommand line flags and the function shall return a list of command\nline flags to use.\")\n\n\f\n;; Internal vars and structs\n(defvar rg-builtin-type-aliases-cache nil\n  \"Cache for \\\"rg --type-list\\\".\")\n\n(defvar rg-prioritized-type-aliases-cache nil\n  \"Cache for `rg-prioritized-type-aliases'.\")\n\n(defvar rg-initial-toggle-flags nil\n  \"List of command line flags set by default by `rg-define-toggle' macro.\")\n\n(defvar rg-history nil \"History for full rg commands.\")\n(defvar rg-files-history nil \"History for files args.\")\n(defvar rg-pattern-history nil \"History for search patterns.\")\n\n(defvar-local rg--executable-local 'unknown)\n\n(defvar rg-required-command-line-flags\n  '(\"--color=always\"\n    \"--colors=match:fg:red\"\n    \"--colors=path:fg:magenta\"\n    \"--colors=line:fg:green\"\n    \"--colors=column:none\"\n    \"-n\"))\n\n(defconst rg-internal-type-aliases\n  '((\"all\" . \"all defined type aliases\") ; rg --type=all\n    (\"everything\" . \"*\")) ; rg without '--type' arg\n  \"Internal type aliases for special purposes.\nThese are not produced by \\\"rg --type-list\\\" but we need them anyway.\")\n\n(defvar rg-global-map\n  (let ((map (make-sparse-keymap)))\n    (define-key map \"d\" 'rg-dwim)\n    (define-key map \"k\" 'rg-kill-saved-searches)\n    (define-key map \"l\" 'rg-list-searches)\n    (define-key map \"p\" 'rg-project)\n    (define-key map \"r\" 'rg)\n    (define-key map \"s\" 'rg-save-search)\n    (define-key map \"S\" 'rg-save-search-as-name)\n    (define-key map \"t\" 'rg-literal)\n    map)\n  \"The global keymap for `rg'.\")\n\n\f\n;; Defuns\n(defun rg-has-connection-local-executable (criteria)\n  \"Return non nil if there is a connection local executable for HOST.\"\n  (when (and (fboundp 'hack-connection-local-variables)\n             (boundp 'connection-local-variables-alist))\n    (hack-connection-local-variables criteria)\n    (assoc 'rg-executable connection-local-variables-alist)))\n\n(defun rg-find-executable ()\n  \"Determine which rg executable to use.\"\n  (let* ((remote-host (file-remote-p default-directory 'host))\n         (criteria `(:application rg :machine ,remote-host)))\n    (if (and remote-host\n             rg-executable-per-connection\n             ;; Below are just to make byte compiler happy\n             (fboundp 'connection-local-set-profile-variables)\n             (fboundp 'connection-local-set-profiles)\n             (fboundp 'hack-connection-local-variables-apply)\n             (fboundp 'with-connection-local-variables))\n        (progn\n          ;; Find executable on remote host once\n          (when (not (rg-has-connection-local-executable criteria))\n            (let ((rg-vars-symbol (intern (concat \"rg-vars-\" remote-host)))\n                  (rg-exec (with-no-warnings (executable-find \"rg\" t))))\n              (connection-local-set-profile-variables\n               rg-vars-symbol\n               `((rg-executable . ,rg-exec)))\n              (connection-local-set-profiles criteria rg-vars-symbol)))\n          ;; Here there should be a remote executable available if found\n          (hack-connection-local-variables-apply criteria)\n          rg-executable)\n      ;; Use local executable for local buffer\n      (default-value 'rg-executable))))\n\n(defun rg-executable ()\n  \"Return the \\\"rg\\\" executable.\nRaises an error if it can not be found.\"\n  (let ((executable (rg-find-executable)))\n    (if executable\n        (shell-quote-argument executable)\n      (user-error \"No 'rg' executable found in host %s\"\n                  (or (file-remote-p default-directory 'host) \"localhost\")))))\n\n(defun rg--buffer-name ()\n  \"Wrapper for variable `rg-buffer-name'.  Return string or call function.\"\n  (if (functionp rg-buffer-name)\n      (funcall rg-buffer-name)\n    rg-buffer-name))\n\n(defun rg-buffer-name (&optional name-of-mode)\n  \"Return search results buffer name.\nNAME-OF-MODE is needed to pass this function to `compilation-start'.\"\n  (ignore name-of-mode)\n  (if rg-recompile\n      (buffer-name)\n    (format \"*%s*\" (rg--buffer-name))))\n\n(defun rg-build-type-add-args ()\n  \"Build a list of --type-add: \\\"foo:*.foo\\\" flags.\nDo this for each type in `rg-custom-type-aliases'.\"\n  (mapcar\n   (lambda (typedef)\n     (let ((name (car typedef))\n           (globs (cdr typedef)))\n       (mapconcat\n        (lambda (glob)\n          (concat \"--type-add=\"\n                  (shell-quote-argument (concat name \":\" glob))))\n        (split-string globs) \" \")))\n   (rg-get-custom-type-aliases)))\n\n(defun rg-is-custom-file-pattern (files)\n  \"Return non nil if FILES is a custom file pattern.\"\n  (not (assoc files (rg-get-type-aliases))))\n\n(defun rg-build-command (pattern files literal flags)\n  \"Create the command line for PATTERN and FILES.\nLITERAL determines if search will be literal or regexp based and FLAGS\nare command line flags to use for the search.\"\n  (let ((command-line\n         (append\n          rg-required-command-line-flags\n          (when (or rg-show-columns rg-group-result)\n            (list \"--column\"))\n          (rg-build-type-add-args)\n          (if (functionp rg-command-line-flags)\n              (funcall rg-command-line-flags)\n            rg-command-line-flags)\n          flags\n\n          (list\n           (if rg-group-result \"--heading\" \"--no-heading\"))\n          (when rg-ignore-ripgreprc\n            (list \"--no-config\"))\n          (when (rg-is-custom-file-pattern files)\n            (list (concat \"--type-add=\" (shell-quote-argument (concat \"custom:\" files)))))\n          (when literal\n            (list \"--fixed-strings\"))\n          (when (not (equal files \"everything\"))\n            (list \"--type=<F>\"))\n          (list \"-e <R>\")\n          (when (member system-type '(darwin windows-nt))\n            (list \".\")))))\n\n    (let ((command (grep-expand-template\n                    (mapconcat 'identity (cons (rg-executable) (delete-dups command-line)) \" \")\n                    pattern\n                    (if (rg-is-custom-file-pattern files) \"custom\" files))))\n      (cond ((and (eq system-type 'windows-nt) rg-w32-unicode)\n             (with-temp-file rg-w32-ripgrep-proxy\n               (set-buffer-multibyte t)\n               (setq buffer-file-coding-system 'utf-8-dos)\n               (insert (format \"@echo off\\n\"))\n               (insert (format \"chcp 65001 > nul\\n\"))\n               (insert (format \"%s\\n\" command)))\n             rg-w32-ripgrep-proxy)\n            (t command)))))\n\n(defun rg-invoke-rg-type-list ()\n  \"Invokes rg --type-list and return the result.\"\n  (shell-command-to-string (concat (rg-executable) \" --type-list\")))\n\n(defun rg-list-builtin-type-aliases ()\n  \"Invokes rg --type-list and puts the result in an alist.\"\n  (let ((type-list (delete \"\" (split-string (rg-invoke-rg-type-list) \"\\n\"))))\n    (mapcar\n     (lambda (type-alias)\n       (setq type-alias (split-string type-alias \":\" t))\n       (cons (string-trim (car type-alias))\n             (string-trim\n              (mapconcat 'identity\n                         (split-string (cadr type-alias) \",\" t )\n                         \" \"))))\n     type-list)))\n\n\n(defun rg-get-custom-type-aliases ()\n  \"Get alist of custom type aliases.\nAny lambda elements will be evaluated, and nil results will be\nfiltered out.\"\n  (delq nil (mapcar\n             (lambda (ct) (if (functionp ct) (funcall ct) ct))\n             rg-custom-type-aliases)))\n\n(defun rg-get-type-aliases (&optional skip-internal)\n  \"Return supported type aliases.\nIf SKIP-INTERNAL is non nil the `rg-internal-type-aliases' will be\nexcluded.\"\n  ;; Read from ripgrep once or if prioritized aliases changed.\n  (unless (and rg-builtin-type-aliases-cache\n               (equal rg-prioritized-type-aliases\n                      (mapcar #'car rg-prioritized-type-aliases-cache)))\n    (let ((builtin-aliases (rg-list-builtin-type-aliases)))\n      (if rg-prioritized-type-aliases\n          (progn\n            (let ((prioritized-type-aliases\n                   (seq-filter (lambda (item)\n                                 (member (car item) rg-prioritized-type-aliases))\n                               builtin-aliases)))\n              ;; Reorder the the found aliases to the same order as rg-prioritized-type-aliases\n              (setq rg-prioritized-type-aliases-cache\n                    (seq-map (lambda (item)\n                               (assoc item prioritized-type-aliases))\n                             rg-prioritized-type-aliases))\n              ;; Remove the prioritzed aliases from the builtin cache\n              ;; to avoid duplicates.\n              (setq rg-builtin-type-aliases-cache\n                    (seq-remove (lambda (item)\n                                  (member (car item) rg-prioritized-type-aliases))\n                                builtin-aliases))))\n        ;; Simple case, just assign\n        (setq rg-builtin-type-aliases-cache builtin-aliases)\n        (setq rg-prioritized-type-aliases-cache nil))))\n  (append (rg-get-custom-type-aliases)\n          rg-prioritized-type-aliases-cache\n          rg-builtin-type-aliases-cache\n          (unless skip-internal rg-internal-type-aliases)))\n\n(defun rg-default-alias ()\n  \"Return the default alias by matching alias globs with the buffer file name.\"\n  (let* ((bufname (or (buffer-file-name)\n                      (replace-regexp-in-string \"<[0-9]+>\\\\'\" \"\" (buffer-name))))\n         (filename (and bufname\n                        (stringp bufname)\n                        (file-name-nondirectory bufname))))\n    (or\n     (when filename\n       (cl-find-if\n        (lambda (alias)\n          (string-match (mapconcat 'wildcard-to-regexp\n                                   (split-string (cdr alias) nil t)\n                                   \"\\\\|\")\n                        filename))\n        (rg-get-type-aliases t)))\n     ;; Default when an alias for the file can't be determined\n     (or\n      (cl-find-if\n       (lambda (alias)\n         (string= rg-default-alias-fallback (car alias)))\n       (rg-get-type-aliases))\n      (progn\n        (message \"Warning: rg-default-alias-fallback customization does not match any alias. Using \\\"all\\\".\")\n        (car rg-internal-type-aliases))))))\n\n(defun rg-tag-default ()\n  \"Get the marked area or thing at point.\nReturns nil if nothing at point.\"\n  (or (and transient-mark-mode mark-active\n\t   (/= (point) (mark))\n\t   (buffer-substring-no-properties (point) (mark)))\n      (funcall (or find-tag-default-function\n\t\t   (get major-mode 'find-tag-default-function)\n\t\t   'find-tag-default))))\n\n(defun rg-read-files ()\n  \"Read files argument for interactive rg.\"\n  (let ((default-alias (rg-default-alias)))\n    (completing-read\n     (concat \"Search in files\"\n             (if default-alias\n                 (concat\n                  \" (default: [\" (car default-alias) \"] = \"\n                  (cdr default-alias) \")\"))\n             \": \")\n     (rg-get-type-aliases)\n     nil nil nil 'rg-files-history\n     (car default-alias))))\n\n(defun rg-read-pattern (literal &optional default)\n  \"Read search pattern argument from user.\nIf LITERAL is non nil prompt for literal string.\nDEFAULT is the default pattern to use at the prompt.\"\n  (let ((default (or default (rg-tag-default)))\n        (prompt (concat (if literal \"Literal\" \"Regexp\")\n                        \" search for\")))\n    (read-regexp prompt default 'rg-pattern-history)))\n\n(defun rg-project-root (file)\n  \"Find the project root of the given FILE.\"\n  (or\n   (when (and (require 'projectile nil t)\n              (fboundp 'projectile-project-root))\n     (projectile-project-root))\n   (when (and (require 'find-file-in-project nil t)\n              (fboundp 'ffip-project-root))\n     (ffip-project-root))\n   (when (and (require 'project nil t)\n              (fboundp 'project-current))\n     (if-let ((project (project-current)))\n         (cond\n          ((fboundp 'project-root)\n           (project-root project))\n          ((fboundp 'project-roots)\n           (car (project-roots project))))))\n   (let ((file (expand-file-name (or file default-directory))))\n     (condition-case nil\n         (vc-call-backend (vc-responsible-backend file) 'root file)\n       (error (file-name-directory file))))))\n\n(defun rg-run (pattern files dir &optional literal confirm flags)\n  \"Execute rg command with supplied PATTERN, FILES and DIR.\nIf LITERAL is nil interpret PATTERN as regexp, otherwise as a literal.\nCONFIRM allows the user to confirm and modify the command before\nexecuting.  FLAGS is additional command line flags to use in the search.\"\n  (unless (and (stringp pattern) (> (length pattern) 0))\n    (signal 'user-error '(\"Empty string: No search done\")))\n  (wgrep-rg-warn-ag-setup)\n  (unless (and (file-directory-p dir) (file-readable-p dir))\n    (setq dir default-directory))\n  (rg-apply-case-flag pattern)\n  (setq dir (file-name-as-directory (expand-file-name dir)))\n  (let* ((flags (append rg-initial-toggle-flags flags))\n         (default-directory dir)\n         (command (rg-build-command\n                   pattern files literal\n                   flags))\n         confirmed)\n    (if confirm\n        (setq confirmed\n              (read-from-minibuffer \"Confirm: \"\n                                    command nil nil 'rg-history))\n      (add-to-history 'rg-history command))\n    (let ((search (rg-search-create\n                   :pattern pattern\n                   :files files\n                   :dir dir\n                   :literal literal\n                   :flags flags)))\n      (when (and confirmed\n                 (not (string= confirmed command)))\n        (setq command confirmed)\n        ;; If user changed command we can't know the parts of the\n        ;; search and needs to disable result buffer modifications.\n        (setf (rg-search-full-command search) command))\n      ;; Since `rg-buffer-name' can be changed through dir-locals file we\n      ;; need to apply variables from dir-locals that resides in search dir.\n      ;; This way the results buffer will receive correct name on `compilation-start'.\n      ;; `hack-dir-local-variables' is searching dir-locals file in\n      ;; `buffer-file-name' or `default-directory' directory.\n      ;; Temporary buffer must be created here to make sure that dir-locals\n      ;; file is loaded from `default-directory' defined above and\n      ;; not from `buffer-file-name' in case search is started from file buffer.\n      (with-temp-buffer\n        (hack-dir-local-variables-non-file-buffer)\n        ;; Setting process-setup-function makes exit-message-function work\n        ;; even when async processes aren't supported.\n        (with-current-buffer (compilation-start command 'rg-mode #'rg-buffer-name)\n          (rg-mode-init search)))))\n  (if (eq next-error-last-buffer (current-buffer))\n      (setq default-directory dir)))\n\n(defun rg-apply-case-flag (pattern)\n  \"Make sure -i is added to the command if needed.\nThe value of the `rg-ignore-case' variable and the case of the\nsupplied PATTERN influences the result.  See `rg-ignore-case' for more\ndetailed info.\"\n  (if (or (eq rg-ignore-case 'force)\n          (and (or (eq rg-ignore-case 'smart)\n                   (and (eq rg-ignore-case 'case-fold-search) case-fold-search))\n               (isearch-no-upper-case-p pattern t)))\n      (setq rg-initial-toggle-flags\n            (add-to-list 'rg-initial-toggle-flags \"-i\" ))\n    (setq rg-initial-toggle-flags\n          (delete \"-i\" rg-initial-toggle-flags))))\n\n(defun rg-get-rename-target ()\n  \"Return the buffer that will be target for renaming.\"\n  (if (eq major-mode 'rg-mode)\n      (current-buffer)\n    (get-buffer (rg-buffer-name))))\n\n(defun rg-get-buffer-file-name ()\n  \"Wrapper for function `buffer-file-name'.\nReturn the result of function `buffer-file-name' if buffer has an\nassociated file, otherwise raise a user error.\"\n  (if (buffer-file-name)\n      (file-name-nondirectory (buffer-file-name))\n    (user-error \"Buffer does not have an associated file\")))\n\n(defalias 'kill-rg 'kill-compilation)\n(defalias 'rg-kill-current 'kill-compilation \"Kill the ongoing ripgrep search.\")\n(make-obsolete 'kill-rg 'rg-kill-current \"1.7.1\")\n\n(defun rg-print-environment ()\n  \"Print the environmet in which this package is running.\nThe result is also copied to the `kill-ring'.  Should be attached to bug\nreports.\"\n  (interactive)\n  (let* ((settings\n          (thread-last (custom-group-members 'rg nil)\n            (seq-filter (lambda (item)\n                          (eq (cadr item) 'custom-variable)))\n            (mapcar (lambda (member)\n                      (cons (car member) (symbol-value (car member)))))))\n         (rg-version (car\n                      (split-string\n                       (shell-command-to-string (format \"%s --version\" (rg-executable)))\n                       \"\\n\")))\n         (compilation-filter-advised\n          (when-let (advice-alist (get 'compilation-filter 'ad-advice-info))\n            (cdr (assoc 'active advice-alist))))\n         (environment (concat\n                       \"--------- RG environment ---------\\n\"\n                       (format \"emacs-version: %s\\n\" (car (split-string (emacs-version) \"\\n\")))\n                       (format \"system: %s\\n\" system-type)\n                       (format \"ripgrep-version: %s\\n\" rg-version)\n                       (format \"compilation-filter-hook: %S\\n\" compilation-filter-hook)\n                       (format \"compilation-filter-advised: %S\\n\" compilation-filter-advised)\n                       (mapconcat\n                        (lambda (setting) (format \"%S: %S\" (car setting) (cdr setting)))\n                        settings \"\\n\")\n                       \"\\n------------------ END ------------------\")))\n    (message environment)\n    (kill-new environment)))\n\n;;;###autoload\n(defmacro rg-define-toggle (flag &optional key default)\n  \"Define a command line flag that can be toggled from the rg result buffer.\n\nThis will create a function with prefix \\\"rg-custom-toggle-flag-\\\"\nconcatenated with the FLAG name, stripped of any leading dashes.  Flag\nmust be a form that will be evaluated to a string at macro expansion\ntime.  For instance, if FLAG is \\\"--invert-match\\\" the function name\nwill be `rg-custom-toggle-flag-invert-match'.  If the flag contains a\nvalue that will be excluded from the function name.\n\nOptional KEY is a key binding that is added to `rg-mode-map'.  If the\noptional DEFAULT parameter is non nil the flag will be enabled by default.\"\n  (let* ((flagvalue (eval flag))\n         (flagname (thread-last (car (split-string flagvalue \" \"  t))\n                     (string-remove-prefix \"-\")\n                     (string-remove-prefix \"-\")))\n         (funname (concat \"rg-custom-toggle-flag-\" flagname)))\n    `(progn\n       ,(if default\n            `(setq rg-initial-toggle-flags\n                   (add-to-list 'rg-initial-toggle-flags ,flagvalue))\n          `(setq rg-initial-toggle-flags\n                 (delete ,flagvalue rg-initial-toggle-flags)))\n       ,(when key\n          `(define-key rg-mode-map ,key (quote ,(intern funname))))\n       (defun ,(intern funname) ()\n         ,(format \"Rerun last search with flag '%s' toggled.\" flagvalue)\n         (interactive)\n         (rg-rerun-toggle-flag ,flagvalue)))))\n\n(defun rg-save-search-as-name (newname)\n  \"Save the search result in current result buffer.\nNEWNAME will be added to the result buffer name.  New searches will use the\nstandard buffer unless the search is done from a saved buffer in\nwhich case the saved buffer will be reused.\"\n  (interactive \"sSave search as name: \")\n  (when-let ((buffer (rg-get-rename-target)))\n    (with-current-buffer buffer\n      (rename-buffer (format \"*%s %s*\" (rg--buffer-name) newname)))))\n\n(defun rg-save-search ()\n  \"Save the search result in current result buffer.\nThe result buffer will be renamed by the `rename-uniquify' function.\nTo choose a custom name, use `rg-save-search-as-name' instead.  New\nsearches will use the standard buffer unless the search is done from\na saved buffer in which case the saved buffer will be reused.\"\n  (interactive)\n  (when-let ((buffer (rg-get-rename-target)))\n    (with-current-buffer buffer\n      (rename-uniquely)\n      ;; If the new buffer name became default result buffer name, just rename\n      ;; again to make sure the result is saved.\n      (when (equal (buffer-name) (rg-buffer-name))\n        (rename-uniquely)))))\n\n(defun rg-kill-saved-searches ()\n  \"Kill all saved rg buffers.  The default result buffer will be kept.\"\n  (interactive)\n  (when (y-or-n-p \"Confirm kill all saved rg searches? \")\n    (dolist (buf (buffer-list))\n      (when (with-current-buffer buf\n              (and (eq major-mode 'rg-mode)\n                   (not (equal (buffer-name) (rg-buffer-name)))))\n        (kill-buffer buf)))))\n\n;;;###autoload\n(defun rg-enable-default-bindings (&optional prefix)\n  \"Enable the global `rg' default key bindings under PREFIX key.\nIf prefix is not supplied `rg-keymap-prefix' is used.\"\n  (interactive)\n  (when-let ((prefix (or prefix rg-keymap-prefix)))\n    (if rg-use-transient-menu\n        (rg-enable-menu prefix)\n      (global-set-key prefix rg-global-map))))\n\n;;;###autoload\n(defun rg-use-old-defaults ()\n  \"Restore default settings pre version 2.0.0.\"\n  (define-key rg-mode-map \"\\C-f\" 'rg-forward-history)\n  (define-key rg-mode-map \"\\C-c>\" nil)\n  (define-key rg-mode-map \"\\C-b\" 'rg-back-history)\n  (define-key rg-mode-map \"\\C-c<\" nil)\n  (define-key rg-mode-map \"\\C-n\" 'rg-next-file)\n  (define-key rg-mode-map \"\\M-N\" nil)\n  (define-key rg-mode-map \"\\C-p\" 'rg-prev-file)\n  (define-key rg-mode-map \"\\M-P\" nil)\n  (define-key rg-mode-map \"l\" 'rg-list-searches)\n  (define-key rg-mode-map \"L\" nil)\n  (define-key rg-mode-map \"w\" 'wgrep-change-to-wgrep-mode)\n  (define-key rg-mode-map \"e\" nil)\n  (setf rg-group-result nil)\n  (setf rg-align-position-numbers nil)\n  (setf rg-align-line-column-separator nil)\n  (setf rg-align-position-content-separator nil)\n  (setf rg-use-transient-menu nil)\n  (setf rg-default-alias-fallback \"all\"))\n\n\n(eval-and-compile\n  (defun rg-set-search-defaults (args)\n    \"Set defaults for required search options missing from ARGS.\nIf the :confirm option is missing, set it to NEVER, if\nthe :format option is missing, set it to REGEXP, and if\nthe :query option is missing, set it to ASK\"\n    (unless (plist-get args :confirm)\n      (setq args (plist-put args :confirm 'never)))\n\n    (unless (plist-get args :format)\n      (setq args (plist-put args :format 'regexp)))\n\n    (unless (plist-get args :query)\n      (setq args (plist-put args :query 'ask)))\n\n    (unless (plist-get args :files)\n      (setq args (plist-put args :files 'ask)))\n\n    (unless (plist-get args :dir)\n      (setq args (plist-put args :dir 'ask)))\n    args))\n\n(eval-and-compile\n  (defun rg-ensure-quoted (arg)\n    \"Ensure that ARG is quoted.\"\n    (if (and (consp arg)\n             (eq (car arg) 'quote))\n        arg\n      `(quote ,arg)))\n\n  (defun rg-ensure-unquoted (arg)\n    \"Ensure that ARG is quoted.\"\n    (if (and (consp arg)\n             (eq (car arg) 'quote))\n        (cadr arg)\n      arg)))\n\n(eval-when-compile\n  ;; parse :format arg, default (non-nil) means to use regexp, otherwise\n  ;; do a literal search\n  (defsubst rg-parse-format-literal (format-opt)\n    (pcase format-opt\n      ('regexp nil)                     ; default to regexp search\n      ('literal t)\n      (_ format-opt))))                 ; otherwise evaluate form\n\n(eval-and-compile\n  (defun rg-search-parse-local-bindings (search-cfg)\n    \"Parse local bindings for search functions from SEARCH-CFG.\"\n    (let* ((confirm-opt (plist-get search-cfg :confirm))\n           (format-opt (plist-get search-cfg :format))\n           (query-opt (plist-get search-cfg :query))\n           (alias-opt (plist-get search-cfg :files))\n           (dir-opt (plist-get search-cfg :dir))\n           (flags-opt (plist-get search-cfg :flags))\n           (literal-opt (rg-parse-format-literal format-opt))\n           (binding-list `((literal ,literal-opt))))\n\n      ;; confirm binding\n      (cond ((eq confirm-opt 'never)\n             (setq binding-list (append binding-list `((confirm nil)))))\n\n            ((eq confirm-opt 'always)\n             (setq binding-list (append binding-list `((confirm t)))))\n\n            ((eq confirm-opt 'prefix)\n             (setq binding-list (append binding-list\n                                        '((confirm (equal current-prefix-arg\n                                                          '(4))))))))\n\n      ;; query binding\n      (unless (eq query-opt 'ask)\n        (let ((query (cond ((eq query-opt 'point) '(or (rg-tag-default)\n                                                       (rg-read-pattern literal)))\n                           (t query-opt))))\n          (setq binding-list (append binding-list `((query ,query))))))\n\n      ;; dir binding\n      (unless (eq dir-opt 'ask)\n        (let ((dirs (cond ((eq dir-opt 'project) '(rg-project-root\n                                                   buffer-file-name))\n                          ((eq dir-opt 'current) 'default-directory)\n                          (t dir-opt))))\n          (setq binding-list (append binding-list `((dir ,dirs))))))\n\n      ;; file alias binding\n      (unless (eq alias-opt 'ask)\n        (let ((files (if (eq alias-opt 'current)\n                         '(car (rg-default-alias))\n                       alias-opt)))\n          (setq binding-list (append binding-list `((files ,files))))))\n\n      (when (eq flags-opt 'ask)\n        (setq flags-opt 'flags))\n\n      (setq flags-opt (rg-ensure-quoted flags-opt))\n      (setq binding-list\n            (append binding-list\n                    `((flags (funcall rg-command-line-flags-function ,flags-opt)))))\n      binding-list)))\n\n(eval-and-compile\n  (defun rg-search-parse-interactive-args (search-cfg)\n    \"Parse interactive args from SEARCH-CFG for search functions.\"\n    (let* ((query-opt (plist-get search-cfg :query))\n           (format-opt (plist-get search-cfg :format))\n           (literal (rg-parse-format-literal format-opt))\n           (dir-opt (plist-get search-cfg :dir))\n           (files-opt (plist-get search-cfg :files))\n           (flags-opt (plist-get search-cfg :flags))\n           (iargs '()))\n\n      (when (eq query-opt 'ask)\n        (setq iargs\n              (append iargs `((query . (rg-read-pattern ,literal))))))\n\n      (when (eq files-opt 'ask)\n        (setq iargs\n              (append iargs '((files . (rg-read-files))))))\n\n      (when (eq dir-opt 'ask)\n        (setq iargs\n              (append iargs\n                      '((dir . (read-directory-name\n                                \"In directory: \" nil default-directory t))))))\n\n      (when (eq flags-opt 'ask)\n        (setq iargs\n              (append iargs '((flags . (split-string\n                                        (read-string \"Command line flags: \")))))))\n      iargs)))\n\n(eval-and-compile\n  (defun rg-search-parse-menu-arg (search-cfg name)\n    \"Parse :menu option in SEARCH-CFG.\nReturns forms for binding function with NAME into rg-menu.\"\n    (when-let ((menu-opt (rg-ensure-unquoted\n                          (plist-get search-cfg :menu))))\n      (unless (and (consp menu-opt)\n                   (= (length menu-opt) 3))\n        (user-error \"'%S' should be a list of length 3\" menu-opt))\n      `((rg-menu-transient-insert\n         ,@menu-opt\n         ',(intern (concat (symbol-name name) \"--transient\")))))))\n\n(defconst rg-elisp-font-lock-keywords\n  '((\"(\\\\(rg-define-search\\\\)\\\\_>[ \\t']*\\\\(\\\\(?:\\\\sw\\\\|\\\\s_\\\\)+\\\\)?\"\n     (1 font-lock-keyword-face)\n     (2 font-lock-function-name-face nil t))))\n\n(font-lock-add-keywords 'emacs-lisp-mode rg-elisp-font-lock-keywords)\n\n;;;###autoload\n(defmacro rg-define-search (name &rest args)\n  \"Define an rg search functions named NAME.\nARGS is a search specification that defines parameters of a search.\nIt optionally starts with a string that is used as the docstring for\nthe defined function.  The rest of ARGS contains key value pairs\naccording to the specification below.  All keys are optional with\nspecified default if left out.\n\n:query      Method for retrieving the search string.  Allowed values\n            are `point' which means extract thing at point and `ask'\n            which means prompt the user for a string.  Any form that\n            evaluates to a string is allowed.\n            Default is `ask'.\n:format     Specifies if :query is interpreted literally (`literal')\n            or as a regexp (`regexp').  If it is a form, eg.\n            (not `current-prefix-arg'), and is non-nil the :query is\n            interpreted literally, otherwise as a regexp.\n            Default is `regexp'.\n:files      Form that evaluates to a file alias or custom file glob.\n            `current' means extract alias from current buffer file name,\n            `ask' will prompt the user.\n            Default is `ask'.\n:dir        Root search directory.  Allowed values are `ask' for user\n            prompt, `current' for current dir and `project' for project\n            root.  Any form that evaluates to a directory string is\n            also allowed.\n            Default is `ask'.\n:confirm    `never', `always', or `prefix' are allowed values.  Specifies\n            if the the final search command line string can be modified\n            and confirmed by the user.\n            Default is `never'.\n:flags      `ask' or a list of command line flags that will be used when\n            invoking the search.\n:menu       Bind the command into `rg-menu'.  Must be a list with three\n            items in it.  The first item is the description of the\n            group in which the new command will appear.  If the group\n            does not exist a new will be created.  The second item is\n            the key binding for this new command (ether a key vector\n            or a key description string) and the third item is the\n            description of the command that will appear in the menu.\n\nExample:\n\\(rg-define-search search-home-dir-in-elisp\n  \\\"Doc string.\\\"\n  :query ask\n  :format literal\n  :files \\\"elisp\\\"\n  :dir (getenv \\\"HOME\\\"\\)\\)\n  :menu (\\\"Custom\\\" \\\"H\\\" \\\"Home dir\\\")\"\n  (declare (indent defun))\n  (let* ((body (macroexp-parse-body args))\n         (decls (car body))\n         (search-cfg (rg-set-search-defaults (cdr body)))\n         (local-bindings (rg-search-parse-local-bindings search-cfg))\n         (iargs (rg-search-parse-interactive-args search-cfg))\n         (menu-forms (rg-search-parse-menu-arg search-cfg name)))\n    `(progn\n       (defun ,name ,(mapcar 'car iargs)\n         ,@decls\n         (interactive\n          (list ,@(mapcar 'cdr iargs)))\n         (let* ,local-bindings\n           (rg-run query files dir literal confirm flags)))\n       (rg-menu-wrap-transient-search ,name)\n       ,@menu-forms)))\n\n;;;###autoload (autoload 'rg-project \"rg.el\" \"\" t)\n(rg-define-search rg-project\n  \"Run ripgrep in current project searching for REGEXP in FILES.\nThe project root will will be determined by either common project\npackages like projectile and `find-file-in-project' or the source\nversion control system.\"\n  :dir project)\n\n;;;###autoload (autoload 'rg-dwim-project-dir \"rg.el\" \"\" t)\n(rg-define-search rg-dwim-project-dir\n  \"Search for thing at point in files matching the current file\nunder the project root directory.\"\n  :query point\n  :format literal\n  :files current\n  :dir project)\n\n;;;###autoload (autoload 'rg-dwim-current-dir \"rg.el\" \"\" t)\n(rg-define-search rg-dwim-current-dir\n  \"Search for thing at point in files matching the current file\nunder the current directory.\"\n  :query point\n  :format literal\n  :files current\n  :dir current)\n\n;;;###autoload (autoload 'rg-dwim-current-file \"rg.el\" \"\" t)\n(rg-define-search rg-dwim-current-file\n  \"Search for thing at point in files matching the current file\nname (as a pattern) under the current directory.\"\n  :query point\n  :format literal\n  :files (rg-get-buffer-file-name)\n  :dir current)\n\n;;;###autoload\n(defun rg-dwim (&optional curdir)\n  \"Run ripgrep without user interaction figuring out the intention by magic(!).\nThe default magic searches for thing at point in files matching\ncurrent file under project root directory.\n\nWith \\\\[universal-argument] prefix (CURDIR), search is done in\ncurrent dir instead of project root.\n\nWith repeated \\\\[universal-argument] prefix, search is done in\nthe current dir and using the current variable `buffer-file-name'\nas a pattern.  Subdirectories are still searched, so different\nfiles with the same name pattern still will be searched.\"\n  (interactive \"P\")\n  (cond\n   ((eq  4 (and (consp curdir) (car curdir))) (rg-dwim-current-dir))\n   ((eq 16 (and (consp curdir) (car curdir))) (rg-dwim-current-file))\n   (t     (rg-dwim-project-dir))))\n\n;;;###autoload (autoload 'rg-literal \"rg.el\" \"\" t)\n(rg-define-search rg-literal\n  \"Run ripgrep, searching for literal PATTERN in FILES in directory DIR.\nWith \\\\[universal-argument] prefix (CONFIRM), you can edit the\nconstructed shell command line before it is executed.\"\n  :format literal\n  :confirm prefix)\n\n;;;###autoload (autoload 'rg \"rg.el\" \"\" t)\n(rg-define-search rg\n  \"Run ripgrep, searching for REGEXP in FILES in directory DIR.\nThe search is limited to file names matching shell pattern FILES.\nFILES may use abbreviations defined in `rg-custom-type-aliases'\nor ripgrep builtin type aliases, e.g. entering `elisp' is\nequivalent to `*.el'. REGEXP is a regexp as defined by the\nripgrep executable. With \\\\[universal-argument] prefix (CONFIRM),\nyou can edit the constructed shell command line before it is\nexecuted. Collect output in a buffer. While ripgrep runs\nasynchronously, you can use \\\\[next-error] (M-x `next-error'), or\n\\\\<grep-mode-map>\\\\[compile-goto-error] \\ in the rg output\nbuffer, to go to the lines where rg found matches.\"\n  :confirm prefix)\n\n(provide 'rg)\n\n;; Local Variables:\n;; byte-compile-warnings: (not cl-functions)\n;; End:\n\n;;; rg.el ends here\n"
  },
  {
    "path": "rgel.info",
    "content": "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\n     Copyright © 2019, David Landell\n\nINFO-DIR-SECTION Emacs\nSTART-INFO-DIR-ENTRY\n* RG: (rgel.info). Search like a King with ripgrep in Emacs.\nEND-INFO-DIR-ENTRY\n\n\n   Generated by Sphinx 7.2.6.\n\n\u001f\nFile: rgel.info,  Node: Top,  Next: Usage,  Up: (dir)\n\nRG User Manual\n**************\n\n     rg.el 2.4.0, Oct 04, 2025\n\n     David Landell\n\n     Copyright © 2019, David Landell\n\n'rg.el' is an Emacs search package based on the ripgrep\n(https://github.com/BurntSushi/ripgrep) command line tool.  It allows\nyou to interactively create searches, doing automatic searches based on\nthe editing context, refining and modifying search results and much\nmore.  It is also highly configurable to be able to fit different users’\nneeds.\n\nThroughout this manual this emacs package will be referred to as 'rg'\nwhile the command line utility will be referred to as 'ripgrep'.\n\nIf you are used to built-in Emacs ‘rgrep’ command, transitioning to 'rg'\nshould be simple.  'rg' provides a lot of extra features but the basics\nare similar.\n\nThe big benefit of using 'ripgrep' instead of 'grep' as a backend is\nspeed.  Especially when searching large source code repositories where\n'ripgrep' really shines.  Please read this blog post\n(http://blog.burntsushi.net/ripgrep/) for some speed comparisons with\nother tools.\n\n* Menu:\n\n* Usage::\n* Configuration::\n* Contribute::\n* License::\n* Index::\n\n\u001f\nFile: rgel.info,  Node: Usage,  Next: Configuration,  Prev: Top,  Up: Top\n\n1 Usage\n*******\n\n* Menu:\n\n* Installation::\n* Searching::\n* Results buffer::\n* Search management::\n* Multi line search::\n\n\u001f\nFile: rgel.info,  Node: Installation,  Next: Searching,  Up: Usage\n\n1.1 Installation\n================\n\nThis version of 'rg' is supported on GNU Emacs 26.1 or later on Linux\nsystems.  It might work on older Emacsen and on other systems but such\nconfigurations are not tested.  Patches for other OS:es are welcome.\n\nMELPA\n.....\n\nPackages are published on MELPA Stable (https://stable.melpa.org/#/rg)\nand MELPA (http://melpa.org/#/rg).  From within Emacs, run ‘M-x\npackage-install [RET] rg [RET]’ to install from those sources.\n\nEnable default key bindings:\n\n     (rg-enable-default-bindings)\n\nThe above will enable the default key map ‘rg-menu’ under the default\nprefix key ‘C-c s’.\n\nManual\n......\n\nReleases can alternatively be downloaded from GitHub\n(https://github.com/dajva/rg.el/releases/latest) and installed manually.\nPut all elisp files in main directory in your load path and ‘require’\nthe package in your init file.\n\n     (require 'rg)\n     (rg-enable-default-bindings)\n\nYou would also need to make sure all package requirements are met.  For\nthis version these are:\n\n   - 'wgrep' 2.1.10\n\n   - 'transient' 0.9.2\n\n   - 'emacs' 26.1\n\n'rg' is using autoloaded symbols which means it’s also possible to defer\nloading if you have autoloading setup.  That usually comes out of the\nbox with ‘package-install’.\n\nLazy loading\n............\n\nFor lazy loading you don’t want to call directly into the package during\nstartup.  Use a setup similar to this instead:\n\n     (global-set-key (kbd \"C-c s\") #'rg-menu)\n     (with-eval-after-load 'rg\n        ;; Your settings goes here.\n     )\n\nIf you don’t want to use the transient menu interface, the following is\nneeded to achieve lazy loading:\n\n     ;; Workaround for emacs' lack of autoloaded keymaps.\n     ;; This is essentially what use-package do.\n     (defun rg-autoload-keymap ()\n       (interactive)\n       (if (not (require 'rg nil t))\n           (user-error (format \"Cannot load rg\"))\n         (let ((key-vec (this-command-keys-vector)))\n           (global-set-key key-vec rg-global-map)\n           (setq unread-command-events\n             (mapcar (lambda (ev) (cons t ev))\n                     (listify-key-sequence key-vec))))))\n\n     (global-set-key (kbd \"C-c s\") #'rg-autoload-keymap)\n     (with-eval-after-load 'rg\n        ;; Your settings goes here.\n     )\n\nwgrep\n.....\n\nThis package use wgrep (https://github.com/mhayashi1120/Emacs-wgrep) for\nediting capabilities in the rg results buffer.  No setup is needed.\n\nIsearch integration\n...................\n\nOptional *note isearch integration: 6. can be enabled to allow you to\nextend isearch to trigger ripgrep searching.  Enable it in your\nconfiguration with:\n\n     (require 'rg-isearch)\n     (define-key isearch-mode-map \"\\M-sr\" 'rg-isearch-menu)\n\nFor the evil use case where isearch-mode is exited after first search\nhit, users would also want to add the binding to the ‘global-map’ or\nsimilar.\n\nInteraction with the 'ripgrep' configuration file\n.................................................\n\nThe 'ripgrep' binary allows using a configuration file\n(https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md#configuration-file)\nto set default values for command line flags.  This package requires\nspecific command line flags to function correctly and using a 'ripgrep'\nconfiguration may conflict with these requirements.  Therefore the\nconfiguration file is ignored by default.  This can be changed by the\n*note rg-ignore-ripgreprc: 7. setting.\n\n     Note: Using the 'ripgrep' configuration file may break\n     functionality of this package if you are not careful.\n\nInteraction with xterm-color\n............................\n\nThis package is not written to be used with custom output colors\nprovided by external packages like 'xterm-color'.  It relies on the\ncolor escape sequences so stripping these will break in unexpected ways.\nIf you are using such packages, the advice is to hook such functionality\ninto ‘compilation-filter-hook’ instead of advising ‘compilation-filter’.\n\n\u001f\nFile: rgel.info,  Node: Searching,  Next: Results buffer,  Prev: Installation,  Up: Usage\n\n1.2 Searching\n=============\n\nSearching is done by invoking one of the different frontend commands.\nThis package is built around recursive search based on three parameters;\na single 'directory', 'file type' filter, and a search 'pattern'.  These\nthree parameters can interactively be selected or figured out\nautomatically by the package, depending on which command that is used.\n\nThe underlying 'ripgrep' binary has the file type filter concept built\nin.  You have a high level of control over which files to search and\nwhich to ignore.  This is partly what makes it so fast, ignoring\nuninteresting files.\n\nIn addition to the base parameters there are a lot of options that\ncontrol how a search is done.  These are typically selected from the\n*note rg-menu: a. interface.\n\n* Menu:\n\n* Case sensitivity::\n* Interactive search::\n* Project search::\n* Do what I mean::\n* Isearch search::\n* File type aliases::\n* The menu::\n\n\u001f\nFile: rgel.info,  Node: Case sensitivity,  Next: Interactive search,  Up: Searching\n\n1.2.1 Case sensitivity\n----------------------\n\nConsidering case when searching is an important feature of any search\ntool.  This package gives you a lot of control over how to handle case\nsensitive and case insensitive search.  It can be forced to 'on' or\n'off' and set to 'smart case'.  The latter is similar to the 'ripgrep'\n‘--smart-case’ flag but is not using the flag directly.  One thing to\nnote about this is that the case insensitive setting controls the\nbehavior when starting a new search.  In the results buffer the setting\nis fixed to 'on' or 'off' but can be toggled easily with a key binding.\nSee *note rg-ignore-case: c. customization for the details of the\nconfiguration.\n\n\u001f\nFile: rgel.info,  Node: Interactive search,  Next: Project search,  Prev: Case sensitivity,  Up: Searching\n\n1.2.2 Interactive search\n------------------------\n\nTwo commands implements fully interactive search, where all the base\nparameters are selected from the mini buffer.\n\n -- ELisp Command: C-c s r (rg)\n\n     This command prompts for 'query', 'file type' and 'directory' and\n     tries to suggest reasonable default values.  The 'query' string is\n     interpreted as a regular expression.  Default for 'query' is the\n     thing at point and for 'directory' it is the current directory.  If\n     the type of the currently visited file is recognized, the\n     corresponding *note file type alias: 10. is suggested as the 'file\n     type' parameter.\n\n     Invoking this command with the 'universal argument' will trigger\n     confirmation and potential modification of the *note full command\n     line: 11. that will invoke the 'ripgrep' binary.\n\n -- ELisp Command: C-c s t (rg-literal)\n\n     This command works in the same way as *note rg: f. but interprets\n     the 'query' string literally and not as a regular expression.\n\n     Invoking this command with the 'universal argument' will trigger\n     confirmation and potential modification of the *note full command\n     line: 11. that will invoke the 'ripgrep' binary.\n\n\u001f\nFile: rgel.info,  Node: Project search,  Next: Do what I mean,  Prev: Interactive search,  Up: Searching\n\n1.2.3 Project search\n--------------------\n\nA common scenario is to search through a whole project while visiting a\nfile in the project.  This essentially means identifying the project\nroot and use that as the top 'directory' when invoking the 'ripgrep'\nbinary.  'rg' supports several ways of identifying a project.  Emacs’\nmajor project packages are supported including projectile\n(https://www.projectile.mx/en/latest/), find-file-in-project\n(https://github.com/technomancy/find-file-in-project) and builtin\nproject.el\n(https://github.com/emacs-mirror/emacs/blob/master/lisp/progmodes/project.el).\nIf none of these are used, the fallback is Emacs’ ‘vc-backend’.\n\n -- ELisp Command: C-c s p (rg-project)\n\n     Search in the current project.  The 'directory' is selected via one\n     of Emacs’ project packages while 'query string' and 'file type' are\n     prompted for.  The 'query string' is interpreted as a regular\n     expression.\n\n\u001f\nFile: rgel.info,  Node: Do what I mean,  Next: Isearch search,  Prev: Project search,  Up: Searching\n\n1.2.4 Do what I mean\n--------------------\n\nThe 'DWIM' family of search commands tries to be smart by figure out the\nsearch parameters from the context without prompting.  Thanks to\n'ripgrep’s' speed, this allows for new ways of searching by invoking a\ndwim command and then 'refine' the search from the results buffer.\n\nThese commands use the word (with the definition of word depending on\ncontext) under cursor as the 'query' string.  The 'file type' parameter\nis taken from the type of the currently visited file.  If the current\nfile type can not be identified all file types known to 'ripgrep' are\nused.  The fallback can be customized with *note\nrg-default-alias-fallback: 18.  The 'directory' parameter varies between\nthese commands.\n\n -- ELisp Command: M-x rg-dwim-project-dir\n\n     Do a 'DWIM' search in the current *note project: 14.\n\n -- ELisp Command: M-x rg-dwim-current-dir\n\n     Do a 'DWIM' search in the current directory.\n\n -- ELisp Command: M-x rg-dwim-current-file\n\n     Do a 'DWIM' search in the current file.  The 'current file' in this\n     context is actually a file 'pattern' exactly matching the current\n     file name in a search starting from current directory.  Most of the\n     time this means a single file but if there are multiple files with\n     the same name in a sub directory, those will be searched as well.\n\n -- ELisp Command: C-c s d (rg-dwim)\n\n     This command combines all the 'DWIM' commands to one.  The default\n     search is in the *note project dir: 19.  With one 'universal\n     argument' *note current directory: 1a. is used and with double\n     'universal arguments' a *note file search: 1b. is done.\n\n\u001f\nFile: rgel.info,  Node: Isearch search,  Next: File type aliases,  Prev: Do what I mean,  Up: Searching\n\n1.2.5 Isearch search\n--------------------\n\nIsearch integration is optional and need to be enabled explicitly in\nyour emacs configuration.  See *note installation: 5. for more info.\n\nThis functionality is similar to emacs built in occur package but offers\nsome additional choices for the search and provides the full\nfunctionality of the rg search result buffer.  When enabled, the choosen\nbinding can be used from isearch to trigger a menu for extending the\nisearch to do a ripgrep search in current file, current directory or\ncurrent project.\n\n\u001f\nFile: rgel.info,  Node: File type aliases,  Next: The menu,  Prev: Isearch search,  Up: Searching\n\n1.2.6 File type aliases\n-----------------------\n\nFile type aliases are used in 'ripgrep' to filter out the files to\nsearch in.  The 'ripgrep' binary comes with a default set of aliases\nthat can be extended or overridden from this package by customizing\n*note rg-custom-type-aliases: 1f.\n\nAn alias is a mapping between a name and a list of glob patterns\n(https://en.wikipedia.org/wiki/Glob_%2528programming%2529) matching the\nfiles of interest.  Selecting an alias when searching is done with\ncompleting read of the defined aliases.  It is also possible to enter a\ncustom glob pattern if there is no suitable alias defined for the file\ntype.\n\n'rg' defines some internal aliases:\n\nName                 Meaning\n                     \n--------------------------------------------------------------------------------------------------------------\n                     \n'all'                all defined types including *note rg-custom-type-aliases: 1f.\n                     \n                     \n'everything'         all files.  No filtering on type is done.\n                     \n                     \n'custom'             used internally in this package for mapping custom glob patterns.\n                     \n\n     Warning: Do not use any of the internal aliases in *note\n     rg-custom-type-aliases: 1f.  That would interfere with the package\n     internal usage.\n\n\u001f\nFile: rgel.info,  Node: The menu,  Prev: File type aliases,  Up: Searching\n\n1.2.7 The menu\n--------------\n\nThe global *note prefix key: 21. may be bound to a transient prefix\ncommand, which means that the key binding will popup a menu.  This\npackage is using the same popup menu backend called transient\n(https://magit.vc/manual/transient) as the magit\n(https://magit.vc/manual/magit) package.  If you are familiar with magit\nthis should feels like home.\n\nThe menu is mostly interesting when you want to give specific command\nline flags to the 'ripgrep' binary.  When you just want to do a quick\nsearch based on the defaults the menu basically acts as a normal keymap.\n\nPressing the ‘rg-menu’ *note prefix key: 21. will popup the menu where\ncommand line flags can be selected before triggering the wanted search\nfunction.  The menu can be customized via the transient API as usual.\nThis package contains some shortcuts to directly add a new command to\nthe menu when defining the command via the *note rg-define-search: 22.\nmacro.\n\n     (rg-define-search rg-word\n       :format literal\n       :flags (\"--word-regexp\")\n       :menu (\"Custom\" \"w\" \"Word\"))\n\nThe ‘:menu’ keyword in the above invocation will trigger insertion of a\nnew menu item bound to key ‘w’ with description 'Word'.  The new menu\nitem will be put under the 'Custom' group.  This group is not available\nin the original menu so it will be created.\n\nThe menu can be triggered from the *note results buffer: 23. with the\n‘m’ key.  The commands in the menu differs, depending on from where it’s\ntriggered but the available options are the same.  The menu does not\nshow all options by default.\n\nThe visible options can be controlled by the transient suffix levels\ndocumented here\n(https://magit.vc/manual/transient/Enabling-and-Disabling-Suffixes.html#Enabling-and-Disabling-Suffixes).\nTo modify what is enabled at the default level 4 press ‘C-x l’ to enter\nedit mode when the menu is visible.  Then select the option by pressing\nthe key sequence that activates the option and choose the level 4 for\nthat option.  It’s also possible to use the transient edit mode for\nmodifying the overall level of the menu to enable more options at once.\n\n\u001f\nFile: rgel.info,  Node: Results buffer,  Next: Search management,  Prev: Searching,  Up: Usage\n\n1.3 Results buffer\n==================\n\nThe results of a search is shown in the results buffer.  This buffer\ndisplays search parameters, the full command line and the output of the\n'ripgrep' binary.  It supports basic navigation between search results\nediting of the file contents directly from the search buffer and also\nmodification of the current search.  The results buffer is a modified\n'compilation' buffer and some key bindings and functionality is\ninherited from the parent and from 'grep mode'.\n\n* Menu:\n\n* Navigation::\n* Refine search::\n* Full command line search::\n* History navigation::\n* Edit and apply (wgrep): Edit and apply wgrep.\n\n\u001f\nFile: rgel.info,  Node: Navigation,  Next: Refine search,  Up: Results buffer\n\n1.3.1 Navigation\n----------------\n\nNavigation works mostly as in grep/compilation buffers.\n\n -- ELisp Command: M-n (compilation-next-error)\n\n     Move to next line with a match.\n\n -- ELisp Command: M-p (compilation-previous-error)\n\n     Move to previous line with a match.\n\n -- ELisp Command: n (next-error-no-select)\n\n     Move to next line with a match, show that file in other buffer and\n     highlight the match.\n\n -- ELisp Command: p (previous-error-no-select)\n\n     Move to previous line with a match, show that file in other buffer\n     and highlight the match.\n\n -- ELisp Command: M-N (rg-next-file)\n\n     Move to next file header if the results is grouped under a file\n     header (See *note rg-group-result: 2b.).\n\n -- ELisp Command: M-P (rg-prev-file)\n\n     Move to previous file header if the results is grouped under a file\n     header (See *note rg-group-result: 2b.).\n\n -- ELisp Command: } (compilation-next-file)\n\n     Move first match in previous file.\n\n -- ELisp Command: { (compilation-previous-file)\n\n     Move last match in previous file.\n\n -- ELisp Command: RET (compile-goto-error)\n\n     Visit match in file.\n\nIf *note rg-group-result: 2b. is enabled, the Imenu\n(https://www.gnu.org/software/emacs/manual/html_node/emacs/Imenu.html)\nfacility is configured to jump across files.\n\n\u001f\nFile: rgel.info,  Node: Refine search,  Next: Full command line search,  Prev: Navigation,  Up: Results buffer\n\n1.3.2 Refine search\n-------------------\n\nFrom the results buffer it’s easy to change the search parameters.  Some\nbindings toggle a flag while others allow you to interactively change\nthe *note base parameters: 9.\n\n -- ELisp Command: d (rg-rerun-change-dir)\n\n     Interactively change search 'directory'.\n\n -- ELisp Command: f (rg-rerun-change-files)\n\n     Interactively change searched 'file types'.\n\n -- ELisp Command: t (rg-rerun-change-literal)\n\n     Interactively change 'search string' interpret the string\n     literally.\n\n -- ELisp Command: r (rg-rerun-change-regexp)\n\n     Interactively change 'search string' interpret the string as a\n     regular expression.\n\n     Tip: *note rg-rerun-change-regexp: 34. and *note\n     rg-rerun-change-literal: 33. are used for switching between regular\n     expression and literal search.  So for quick switching between\n     search modes with the same search string, just press the respective\n     key and then ‘RET’.\n\n -- ELisp Command: g (rg-recompile)\n\n     Rerun the current search without changing any parameters.\n\n -- ELisp Command: c (rg-rerun-toggle-case)\n\n     Toggle case sensitivity of search.  The state of the flag is shown\n     in the '[case]' header field.\n\n -- ELisp Command: i (rg-rerun-toggle-ignore)\n\n     Toggle if ignore files are respected.  The state of the flag is\n     shown in the '[ign]' header field.\n\n     Tip: It is possible to create and bind your own toggle flags with\n     the macro *note rg-define-toggle: 38.\n\n -- ELisp Command: m (rg-menu)\n\n     Fire up *note the menu: a. for full access to options and flags.\n\n\u001f\nFile: rgel.info,  Node: Full command line search,  Next: History navigation,  Prev: Refine search,  Up: Results buffer\n\n1.3.3 Full command line search\n------------------------------\n\nSome search commands (See *note rg: f. or *note rg-literal: 12.) allow\nyou to edit the final command line before invoking the search by giving\na 'universal argument'.  This can be used to invoke features of the\n'ripgrep' binary that is not supported in this package’s interface.\nThis could be specific flags, searching in multiple directories etc.\n\n     Note: Using full command line search will disable refinement of the\n     search from the result buffer.\n\n\u001f\nFile: rgel.info,  Node: History navigation,  Next: Edit and apply wgrep,  Prev: Full command line search,  Up: Results buffer\n\n1.3.4 History navigation\n------------------------\n\nEach search result is stored in the search history, which is a per\nresults buffer property.  History can be navigated back and forward, the\nforward history is cleared when a new search is done.\n\n -- ELisp Command: C-c < (rg-back-history)\n\n     Navigate back in history.\n\n -- ELisp Command: C-c > (rg-forward-history)\n\n     Navigate forward in history.\n\n     Tip: The key bindings here are slightly inconvenient so invoking\n     this via *note the menu: a. by pressing ‘m b’ and ‘m w’ is more\n     ergonomic.\n\n\u001f\nFile: rgel.info,  Node: Edit and apply wgrep,  Prev: History navigation,  Up: Results buffer\n\n1.3.5 Edit and apply (wgrep)\n----------------------------\n\nThe results buffer supports inline editing via the wgrep\n(https://github.com/mhayashi1120/Emacs-wgrep) package.  This is setup\nautomatically when 'rg' is loaded.\n\n -- ELisp Command: e (wgrep-change-to-wgrep-mode)\n\n     Make the search results editable by enabling ‘wgrep’ mode.  When\n     done press ‘C-c C-c’ to commit your changes to the underlying files\n     or ‘C-c C-k’ to drop the changes.\n\n\u001f\nFile: rgel.info,  Node: Search management,  Next: Multi line search,  Prev: Results buffer,  Up: Usage\n\n1.4 Search management\n=====================\n\nThe result buffer is named ‘*rg*’ and 'rg' reuse the same result buffer\nfor new searches.  If you want to store a search while continuing doing\nnew searches there are two ways of doing that.\n\n -- ELisp Command: s (rg-save-search)\n\n     Save the search buffer by renaming it to a unique new name.  This\n     is available both outside and inside a result buffer.  Outside of\n     the result buffer it’s bound to ‘C-c s s’.\n\n     If you want to keep all search buffers until manually killed you\n     can use this snippet in your init file.\n\n          (defadvice rg-run (before rg-run-before activate)\n            (rg-save-search))\n\n -- ELisp Command: S (rg-save-search-as-name)\n\n     Save the search buffer and interactively give it a specific name.\n     This is available both outside and inside a result buffer.  Outside\n     of the result buffer it’s bound to ‘C-c s S’.\n\nThe default buffer name can be customized with *note rg-buffer-name: 46.\nThis setting considers dir local variables and it’s even possible to use\na function to get a really dynamic setup.\n\nHaving a lot of search buffers floating around can easily get messy.  To\nhelp keeping this under control there is a search manager.  The manager\nis simply a modified ‘ibuffer’ that lists all the results buffers, shows\nsome data about the searches and make it possible to kill of some unused\netc.\n\n -- ELisp Command: L (rg-list-searches)\n\n     Open the search manager.  This is available both in result buffer\n     and globally bound to ‘C-c s l’.\n\n -- ELisp Command: C-c s k (rg-kill-saved-searches)\n\n     Kill all saved searches except for the one that matches *note\n     rg-buffer-name: 46.  This is available both in result buffer and\n     globally bound to ‘C-c s k’.\n\n     Warning: If you have a dynamic *note rg-buffer-name: 46. setup,\n     only one buffer that matches your current criteria (dir locals or\n     project for instance) will be kept.  So be careful when killing\n     saved searches to avoid losing important search results.\n\n\u001f\nFile: rgel.info,  Node: Multi line search,  Prev: Search management,  Up: Usage\n\n1.5 Multi line search\n=====================\n\nBy default, ripgrep does matching per line.  The ‘--multiline’ flag can\nbe used for enabling matching over multiple lines.  This flag is\navailable in the *note rg-menu: a. as an option.  The ‘--multiline’ flag\ndoes not match new line characters with the ‘.’ as one might expect\nthough.  A separate flag is used to allow this, ‘--multiline-dotall’.\nThe casual user of multi line search commonly want this flag on by\ndefault so it’s recommended to add this to *note rg-command-line-flags:\n4b. to avoid having to trigger this flag manually from the menu.\n\nSee the ripgrep manual page for more info about the multi line flags.\n\n\u001f\nFile: rgel.info,  Node: Configuration,  Next: Contribute,  Prev: Usage,  Up: Top\n\n2 Configuration\n***************\n\n* Menu:\n\n* Customization::\n* Faces::\n* Configuration functions::\n* Hooks::\n* Configuration macros::\n* Use with evil-mode::\n* Customizing the menu::\n\n\u001f\nFile: rgel.info,  Node: Customization,  Next: Faces,  Up: Configuration\n\n2.1 Customization\n=================\n\nCustomization is done via the Emacs customization system.  The group\n‘rg’ is the main group of the package.\n\n     M-x customize-group [RET] rg [RET]\n\n -- ELisp Variable: rg-executable [(executable-find \"rg\")]\n\n     The 'ripgrep' executable to use.  Could be an absolute path or just\n     the base name if the executable is in the path.  The default is\n     using ‘executable-find’ to locate the command.  If you want to use\n     this package with tramp it might be better to set it to just “rg”\n     in order to let the OS find the binary where it’s invoked.  From\n     Emacs 27.1, the tramp use case is by default handled automatically.\n     See *note rg-executable-per-connection: 51. for details.\n\n -- ELisp Variable: rg-executable-per-connection [t]\n\n     This setting only has effect in Emacs 27.1 or later.  Handle the\n     *note rg-executable: 50. automatically for different hosts if used\n     with tramp.  ‘executable-find’ for “rg” binary will be invoked on\n     remote hosts to determine the path to ripgrep.  The result is\n     stored per connection.\n\n -- ELisp Variable: rg-custom-type-aliases [nil]\n\n     An association list that maps file type aliases to a space\n     delimited string with file globs.  These are combined with the\n     'ripgrep' builtin file aliases.\n\n     Example:\n\n          (setq rg-custom-type-aliases\n            '((\"foo\" .    \"*.foo *.bar\")\n              (\"baz\" .    \"*.baz *.qux\")))\n\n     You may also add lambdas to ‘rg-custom-type-aliases’ to add aliases\n     dynamically based on mode, directory, project, etc.\n\n          (add-to-list\n           'rg-custom-type-aliases\n           (lambda ()\n             (when (in-frontend-app)\n               (cons \"ui\" \"*.js *.hbs *.json\"))))\n\n -- ELisp Variable: rg-prioritized-type-aliases [nil]\n\n     A list of aliases that are prioritized among ripgrep’s builtin\n     aliases when selecting the alias based on the buffer file name.\n     This list contains only the alias names and the order between the\n     items does not matter.\n\n     Example:\n\n          (setq rg-custom-type-aliases\n            '(\"cpp\" \"puppet\"))\n\n -- ELisp Variable: rg-default-alias-fallback [\"everything\"]\n\n     This setting controls the default alias used when no alias can be\n     recognized for the current buffer.  ‘all’ or ‘everything’ are\n     reasonable values for this variable.\n\n -- ELisp Variable: rg-command-line-flags [nil]\n\n     A list of command line flags that will be appended to the 'ripgrep'\n     command line.  Must either be a list of flags or a function that\n     returns a list of flags.\n\n -- ELisp Variable: rg-group-result [t]\n\n     Controls the layout of the results buffer.  If non ‘nil’, each file\n     name is displayed once and matches are grouped under that filename\n     instead of repeating the filename on each match.  This is\n     essentially the layout of the ‘--no-heading’ 'ripgrep' command line\n     flag.\n\n -- ELisp Variable: rg-show-columns [nil]\n\n     Controls if column numbers are used in the search result.\n\n -- ELisp Variable: rg-ignore-case [case-fold-search]\n\n     Setting that controls if case sensitive search is made or not.  It\n     can essentially be 'on', 'off' or 'smart'.  The 'smart' setting\n     will trigger an analyze of the search string and if it’s all lower\n     case, the search will be case 'insensitive', otherwise it will be\n     case 'sensitive'.  The following values are valid:\n\n        - 'case-fold-search' - A non nil value of ‘case-fold-search’\n          will trigger smart case behavior.\n\n        - 'smart' - Smart case behavior.\n\n        - 'force' - Always ignore case.\n\n        - 'nil' - Always consider case.\n\n -- ELisp Variable: rg-hide-command [t]\n\n     Hide most of command line by default.  This is enabled by default\n     and can be set to ‘nil’ to show full command line.  This can be\n     toggled in the results buffer by clicking on the command line.\n\n -- ELisp Variable: rg-keymap-prefix [\"C-c s\"]\n\n     This variable sets the default prefix used for the global key\n     bindings.  Note that ‘rg-enable-default-bindings’ needs to be\n     invoked for the bindings to be enabled.\n\n -- ELisp Variable: rg-use-transient-menu [t]\n\n     Controls whether ‘rg-menu’ will be used by default or not.  It’s\n     also possible to enable the menu explicitly with\n\n          (rg-enable-menu)\n\n -- ELisp Variable: rg-show-header [t]\n\n     Controls if the search info header is shown in the result buffer.\n     This is enabled by default but can be disabled by setting this\n     variable to ‘nil’.\n\n -- ELisp Variable: rg-buffer-name [\"rg\"]\n\n     Controls the name of the results buffer.  It may be 'string' or\n     'function'.  This name will be surrounded by ‘*’ to yield the final\n     buffer name so if this setting is ‘foo’ the buffer name will be\n     ‘*foo*’.  One useful case of using it is to have separate result\n     buffers per project.  One can set this variable in 'dir-locals'\n     file or set it to function.\n\n     Example, this function will set results buffer name based on\n     'project-current':\n\n          (defun my-rg-buffer-name ()\n            (let ((p (project-current)))\n              (if p\n           (format \"rg %s\" (abbreviate-file-name (cdr p)))\n                \"rg\")))\n\n -- ELisp Variable: rg-ignore-ripgreprc [t]\n\n     Controls if the ripgreprc\n     (https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md#configuration-file)\n     file should be ignored or not.  If ‘nil’, the config file will be\n     used, otherwise it will be ignored.  The default is to ignore this\n     file in order to avoid that conflicting settings have impact on\n     this package’s behavior.  Setting this to ‘nil’ may affect core\n     functionality of this package.  Especially changing colors can\n     affect parsing of the output and result in a broken results buffer.\n\n* Menu:\n\n* Position numbers alignment::\n\n\u001f\nFile: rgel.info,  Node: Position numbers alignment,  Up: Customization\n\n2.1.1 Position numbers alignment\n--------------------------------\n\nWhen operating 'rg' in grouped output mode (*note rg-group-result: 2b.\nis non nil), it’s possible to control how the line and column numbers\nare displayed in the result buffer.\n\nExample settings:\n\n     (setq rg-align-position-numbers t)\n     (setq rg-align-line-number-field-length 3)\n     (setq rg-align-column-number-field-length 3)\n     (setq rg-align-line-column-separator \"#\")\n     (setq rg-align-position-content-separator \"|\")\n\nWill yield the following format:\n\n     File: matched_file.foo\n       1#  2|match1\n     888# 10|match2\n\n -- ELisp Variable: rg-align-position-numbers [t]\n\n     Setting this to ‘t’ will align line and column numbers in columns\n     padded with white space.\n\n -- ELisp Variable: rg-align-line-number-field-length [4]\n\n     Defines the length of the line number field.\n\n -- ELisp Variable: rg-align-column-number-field-length [3]\n\n     Defines the length of the column number field.\n\n -- ELisp Variable: rg-align-line-column-separator [\" \"]\n\n     Separator string used between line and column numbers.  ‘nil’ means\n     use default separator from 'ripgrep'.\n\n -- ELisp Variable: rg-align-position-content-separator [\" \"]\n\n     Separator string used between the position numbers and matched\n     content.  ‘nil’ means use default separator from 'ripgrep'.\n\n\u001f\nFile: rgel.info,  Node: Faces,  Next: Configuration functions,  Prev: Customization,  Up: Configuration\n\n2.2 Faces\n=========\n\nAll faces are in the subgroup ‘rg-face’ of the main group ‘rg’.\n\n     M-x customize-group [RET] rg-face [RET]\n\n* Menu:\n\n* Results buffer: Results buffer<2>.\n* Header line::\n\n\u001f\nFile: rgel.info,  Node: Results buffer<2>,  Next: Header line,  Up: Faces\n\n2.2.1 Results buffer\n--------------------\n\n -- ELisp Variable: rg-match-face [match]\n\n     Face used to highlight matches in result.\n\n -- ELisp Variable: rg-error-face [compilation-error]\n\n     Face used to highlight errors when invoking 'ripgrep'.\n\n -- ELisp Variable: rg-context-face [shadow]\n\n     Face used to highlight context lines in 'ripgrep' output when\n     ‘--context-lines’ flag is used.\n\n -- ELisp Variable: rg-info-face [compilation-info]\n\n     Face used to highlight general info in results buffer.  For\n     instance the number of matches found.\n\n -- ELisp Variable: rg-warning-face [compilation-warning]\n\n     Face used to highlight warnings in the 'ripgrep' output.\n\n -- ELisp Variable: rg-filename-face [rg-info-face]\n\n     Face used to highlight filenames in the output.\n\n -- ELisp Variable: rg-file-tag-face [rg-info-face]\n\n     Face used for the ‘File:’ tag in grouped results output.\n\n -- ELisp Variable: rg-line-number-face [compilation-line-number]\n\n     Face used on line numbers.\n\n -- ELisp Variable: rg-column-number-face [compilation-column-number]\n\n     Face used on column numbers.\n\n -- ELisp Variable: rg-match-position-face [default]\n\n     Face added to file positions.  This is the start of a matching line\n     and depending on configuration may be, file name, column number and\n     line number.\n\n\u001f\nFile: rgel.info,  Node: Header line,  Prev: Results buffer<2>,  Up: Faces\n\n2.2.2 Header line\n-----------------\n\n -- ELisp Variable: rg-toggle-on-face [rg-file-tag-face]\n\n     Face used for flags that are toggled ‘on’.\n\n -- ELisp Variable: rg-toggle-off-face [rg-error-face]\n\n     Face used for flags that are toggled ‘off’.\n\n -- ELisp Variable: rg-literal-face [rg-filename-face]\n\n     Face used the on the ‘literal’ marker in the header line.\n\n -- ELisp Variable: rg-regexp-face [compilation-line-number]\n\n     Face used the on the ‘regexp’ marker in the header line.\n\n\u001f\nFile: rgel.info,  Node: Configuration functions,  Next: Hooks,  Prev: Faces,  Up: Configuration\n\n2.3 Configuration functions\n===========================\n\n -- ELisp Function: (rg-enable-default-bindings &optional, prefix)\n\n     Enable the default keyboard bindings for the package with prefix\n     key.  If *note rg-use-transient-menu: 55. is on this will enable\n     the menu instead of activating the global bindings.  If ‘prefix’ is\n     not provided *note rg-keymap-prefix: 21. will be used.\n\n -- ELisp Function: (rg-enable-menu &optional, prefix)\n\n     Enable the *note rg-menu: a. with prefix key.  This bypass *note\n     rg-use-transient-menu: 55. setting.  If ‘prefix’ is not provided\n     *note rg-keymap-prefix: 21. will be used.\n\n -- ELisp Function: (rg-use-old-defaults)\n\n     This function is provided to keep backwards compatibility with\n     versions older than 2.0.0.  In this version default settings as\n     well as key bindings changed and to bring back the old defaults\n     call this function in your init file.\n\n\u001f\nFile: rgel.info,  Node: Hooks,  Next: Configuration macros,  Prev: Configuration functions,  Up: Configuration\n\n2.4 Hooks\n=========\n\n -- ELisp Variable: rg-finish-functions [nil]\n\n     Functions to call when a ripgrep search is finished.\n\n     Each function is called with two arguments: the compilation buffer,\n     and a string describing how the process finished.\n\n -- ELisp Variable: rg-filter-hook [nil]\n\n     Hook run after new content has been inserted in in the rg buffer.\n     This hook is called every time the rg buffer has been updated with\n     new content and filtered internally by the package.\n\n -- ELisp Variable: rg-mode-hook [(wgrep-rg-setup)]\n\n     Hook run after entering rg mode.\n\n\u001f\nFile: rgel.info,  Node: Configuration macros,  Next: Use with evil-mode,  Prev: Hooks,  Up: Configuration\n\n2.5 Configuration macros\n========================\n\n -- ELisp Function: (rg-define-toggle flag, &optional, key, default)\n\n     This is a macro that can be used to define custom 'ripgrep' flag\n     toggling functions in the result buffer.  The macro takes the flag\n     (and potential value) as an argument and optionally binds the\n     toggle function to a key.  If ‘default’ is non nil the flag is used\n     by default.\n\n     The function defined by this macro will be named as the flag name\n     stripped with leading dashes and prefixed with\n     ‘rg-custom-toggle-flag-’.\n\n          (rg-define-toggle \"-uu\" \"I\" t)\n\n     Creates a function named ‘rg-custom-toggle-flag-uu’ that is on by\n     default and bound to ‘I’ in 'rg' result buffer.\n\n          (rg-define-toggle \"--context 3\" (kbd \"C-c c\"))\n\n     Creates a function named ‘rg-custom-toggle-flag-context’ that is\n     off by default and bound to ‘C-c c’ in 'rg' result buffer.\n\n -- ELisp Function: (rg-define-search name, &rest, args)\n\n     This macro can be used to define custom search functions in a\n     declarative style.  Default implementations for common behavior is\n     available and custom forms can also be used.\n\n     It optionally starts with a string that is used as the docstring\n     for the defined function.  The rest of the arguments contain key\n     value pairs according to the specification below.  All keys are\n     optional with specified default if left out.\n\n        - ':query' - Method for retrieving the search string.  Allowed\n          values are ‘point’ which means extract thing at point and\n          ‘ask’ which means prompt the user for a string.  Any form that\n          evaluates to a string is allowed.  Default is ‘ask’.\n\n        - ':format' - Specifies if ‘:query’ is interpreted literally\n          (‘literal’) or as a regexp (‘regexp’).  If it is a form, eg.\n          ‘(not current-prefix-arg)’, and is non-nil the ‘:query’ is\n          interpreted literally, otherwise as a regexp.  Default is\n          ‘regexp’.\n\n        - ':files' - Form that evaluates to a file alias or custom file\n          glob.  ‘current’ means extract alias from current buffer file\n          name, ‘ask’ will prompt the user.  Default is ‘ask’.\n\n        - ':dir' - Root search directory.  Allowed values are ‘ask’ for\n          user prompt, ‘current’ for current dir and ‘project’ for\n          project root.  Any form that evaluates to a directory string\n          is also allowed.  Default is ‘ask’.\n\n        - ':confirm' - ‘never’, ‘always’, or ‘prefix’ are allowed\n          values.  Specifies if the the final search command line string\n          can be modified and confirmed the user.  Default is ‘never’.\n\n        - ':flags' - ‘ask’ or a list of command line flags that will be\n          used when invoking the search.\n\n        - ':menu' - Bind the command into ‘rg-menu’.  Must be a list\n          with three items in it.  The first item is the description of\n          the group in which the new command will appear.  If the group\n          does not exist a new will be created.  The second item is the\n          key binding for this new command (ether a key vector or a key\n          description string) and the third item is the description of\n          the command that will appear in the menu.\n\n     Examples:\n\n          (rg-define-search search-everything-at-home\n            \"Search files including hidden in home directory\"\n            :query ask\n            :format literal\n            :files \"everything\"\n            :flags (\"--hidden\")\n            :dir (getenv \"HOME\")\n            :menu (\"Search\" \"h\" \"Home\"))\n\n          (rg-define-search rg-emacs\n            \"Search the emacs lisp source code.\"\n            :dir \"/usr/share/emacs/25.2/lisp/\"\n            :flags '(\"-z\")\n            :files \"*.{el,el.gz}\"\n            :menu (\"Custom\" \"L\" \"lisp\"))\n\n\u001f\nFile: rgel.info,  Node: Use with evil-mode,  Next: Customizing the menu,  Prev: Configuration macros,  Up: Configuration\n\n2.6 Use with evil-mode\n======================\n\nSome key bindings clash with 'evil-mode'.  Recommendation is to use evil\n'motion' state for the results buffer and then switch to evil 'normal'\nmode when editing in 'wgrep-mode'.  Some adjustments need to be done to\navoid the clashes though.\n\nThis is a start of a configuration.  This let 'rg-mode'’s key bindings\noverride the motion state map bindings based on that these motion keys\nare not important in an 'rg' results buffer.  Adjust this to your\npreferred use case:\n\n     (with-eval-after-load 'rg\n       (advice-add 'wgrep-change-to-wgrep-mode :after\n               #'evil-normal-state)\n       (advice-add 'wgrep-to-original-mode :after\n               #'evil-motion-state)\n       (defvar rg-mode-map)\n       (add-to-list 'evil-motion-state-modes 'rg-mode)\n       (evil-add-hjkl-bindings rg-mode-map 'motion\n         \"e\" #'wgrep-change-to-wgrep-mode\n         \"g\" #'rg-recompile\n         \"t\" #'rg-rerun-change-literal))\n\n\u001f\nFile: rgel.info,  Node: Customizing the menu,  Prev: Use with evil-mode,  Up: Configuration\n\n2.7 Customizing the menu\n========================\n\nThe menu can be modified from the emacs configuration file.\n\nTo add a new 'switch' before the option triggered by ‘-n’ at suffix\nlevel 3:\n\n     (transient-insert-suffix 'rg-menu \"-n\" '(3 \"-o\" \"Only print matches\" \"--only-matching\"))\n\nTo add a new 'option' before the option triggered by ‘-g’ at suffix\nlevel 4:\n\n     (transient-insert-suffix 'rg-menu \"-g\" '(4 \"-f\" \"Pattern file\" \"--file=\"))\n\nThe ‘=’ in ‘--file=’ triggers argument input for the flag.\n\nTo remove an item from the menu specify the trigger key in the transient\nremove command.  For example, to remove the ‘Search hidden files’ switch\nuse the following:\n\n     (transient-remove-suffix 'rg-menu \"-h\")\n\nPlease refer to the transient\n(https://magit.vc/manual/transient/Modifying-Existing-Transients.html#Modifying-Existing-Transients)\ndocumentation for details on customizing the menu.\n\nThis package also adds a convenience function for appending new\n'commands' to the menu in the groups at the bottom.\n\n -- ELisp Function: (rg-menu-transient-insert group, key, description,\n          command)\n\n     This inserts a new command under ‘group’ if it exists, otherwise a\n     new group is created.  ‘key’, ‘description’ and ‘command’ is as for\n     the ‘transient-insert-suffix’ function.\n\n     For example to insert a new command under ‘Search’ group:\n\n          (rg-menu-transient-insert \"Search\" \"m\" \"My search\" 'my-search-command)\n\n     It’s usually better to use the ‘:menu’ key of the *note\n     rg-define-search: 22. macro to define a search function and adding\n     it to the menu in one go.\n\n\u001f\nFile: rgel.info,  Node: Contribute,  Next: License,  Prev: Configuration,  Up: Top\n\n3 Contribute\n************\n\nContributions are very welcome.  Development is done in the GitHub\nrepository (https://github.com/dajva/rg.el).  If you find a bug, please\nreport it in the issue tracker (https://github.com/dajva/rg.el/issues).\n\n* Menu:\n\n* Pull requests::\n* Docker::\n* Tests::\n* Documentation::\n\n\u001f\nFile: rgel.info,  Node: Pull requests,  Next: Docker,  Up: Contribute\n\n3.1 Pull requests\n=================\n\nIf you want to submit a patch, please submit a GitHub pull request\n(https://github.com/dajva/rg.el/pulls).  If you want to submit any\nlarger code changes, please create an issue first for discussion.  Some\nfeatures does not fit well into this package and there is also good to\nagree on the general design before doing any major work.\n\nThe minimum requirements for a pull request to be accepted is that all\nexisting tests pass and test coverage should not decrease.  Often a\npatch also needs additional tests, new/changed documentation etc.\n\nDon’t strive to submit a perfect pull request directly.  It’s often\nbetter to submit something simple that shows the main direction of the\nnew code in order to discuss the best way to proceed and what additions\nare needed.\n\n\u001f\nFile: rgel.info,  Node: Docker,  Next: Tests,  Prev: Pull requests,  Up: Contribute\n\n3.2 Docker\n==========\n\nDocker can be used to run the tests or generate documentation locally\nwithout installing dependencies on the host and to test with different\nemacs versions.\n\nTo use docker, just set the ‘USE_DOCKER’ variable when running the\ntests.  The ‘EMACS_VERSION’ variable can be used to select emacs\nversion.  Note that dash (‘-’) is used instead of points (‘.’) in the\nversion numbering.  So emacs 28.2 is specified as ‘28-2’.  Emacs are\ninstalled from ‘https://github.com/purcell/nix-emacs-ci’ so only emacs\nversions supported in that repository will work.\n\n   - Build docker container:\n\n          # Don't use the USE_DOCKER variable here\n          make EMACS_VERSION=26-2 docker-build\n\n   - To run all the tests in docker image:\n\n          make USE_DOCKER=true test\n\n   - Use a specific emacs version:\n\n          make USE_DOCKER=true EMACS_VERSION=snapshot\n\n   - Generate html documentation:\n\n          make USE_DOCKER=true html\n\n\u001f\nFile: rgel.info,  Node: Tests,  Next: Documentation,  Prev: Docker,  Up: Contribute\n\n3.3 Tests\n=========\n\nCask (https://cask.readthedocs.io/) is used for testing.  The tests are\nwritten using the Emacs built in ERT framework and follows the\nconventions of ert runner (https://github.com/rejeep/ert-runner.el)\nalthough ert_runner is no longer used.  There are also compilation\ntests, style check, package verification etc.\n\n* Menu:\n\n* Setup::\n* Running::\n\n\u001f\nFile: rgel.info,  Node: Setup,  Next: Running,  Up: Tests\n\n3.3.1 Setup\n-----------\n\n   - Install cask\n     (https://cask.readthedocs.io/en/latest/guide/installation.html)\n\n   - Install all developer dependencies:\n\n          make deps\n\n\u001f\nFile: rgel.info,  Node: Running,  Prev: Setup,  Up: Tests\n\n3.3.2 Running\n-------------\n\n   - Run the whole test suite:\n\n          make test\n\n   - Run only the unit/integration tests:\n\n          make ert-test\n\n   - Manually test the package with Emacs:\n\n          cask emacs -Q -L . --eval=\"(progn (require 'rg) (enable-default-bindings))\"\n\n\u001f\nFile: rgel.info,  Node: Documentation,  Prev: Tests,  Up: Contribute\n\n3.4 Documentation\n=================\n\nThe documentation is written in org mode.  The export target is\nrestructured text\n(https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html)\nsuitable for the Sphinx (http://www.sphinx-doc.org/en/master/)\ndocumentation generator.  Sphinx is used to export the output from org\nmode to info and HTML documentation.  The resulting .rst files are used\nfor the online documentation on ‘https://readthedocs.io’.\n\nThe end user documentation is generated after committing to the main\nrepository.  It’s advisable to build both html and info documentation\nlocally and verify the output to make sure the changes looks as\nexpected.\n\n* Menu:\n\n* Setup: Setup<2>.\n* Building::\n\n\u001f\nFile: rgel.info,  Node: Setup<2>,  Next: Building,  Up: Documentation\n\n3.4.1 Setup\n-----------\n\n   - Install Sphinx\n     (http://www.sphinx-doc.org/en/master/usage/installation.html)\n\n          sudo apt install python3-sphinx python3-sphinx-rtd-theme\n\n   - Install makeinfo\n\n          sudo apt install texinfo\n\n\u001f\nFile: rgel.info,  Node: Building,  Prev: Setup<2>,  Up: Documentation\n\n3.4.2 Building\n--------------\n\n   - HTML documentation\n\n          make html\n\n     Open ‘docs/rst/_build/html/index.html’ in a browser.\n\n   - Info documentation\n\n          make info\n\n     To view in emacs:\n\n          C-u M-x info [RET]\n\n     Then select the ‘docs/rst/_build/info/rgel.info’ file.\n\n\u001f\nFile: rgel.info,  Node: License,  Next: Index,  Prev: Contribute,  Up: Top\n\n4 License\n*********\n\n'rg' is free software; you can redistribute it and/or modify it under\nthe terms of the GNU General Public License as published by the Free\nSoftware Foundation; either version 3 of the License, or (at your\noption) any later version.\n\n'rg' is distributed in the hope that it will be useful, but WITHOUT ANY\nWARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE. See the *note GNU General Public\nLicense: 94. for more details.\n\n* Menu:\n\n* GNU General Public License::\n\n\u001f\nFile: rgel.info,  Node: GNU General Public License,  Up: License\n\n4.1 GNU General Public License\n==============================\n\n                         GNU GENERAL PUBLIC LICENSE\n                            Version 3, 29 June 2007\n\n      Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n      Everyone is permitted to copy and distribute verbatim copies\n      of this license document, but changing it is not allowed.\n\n                                 Preamble\n\n       The GNU General Public License is a free, copyleft license for\n     software and other kinds of works.\n\n       The licenses for most software and other practical works are designed\n     to take away your freedom to share and change the works.  By contrast,\n     the GNU General Public License is intended to guarantee your freedom to\n     share and change all versions of a program--to make sure it remains free\n     software for all its users.  We, the Free Software Foundation, use the\n     GNU General Public License for most of our software; it applies also to\n     any other work released this way by its authors.  You can apply it to\n     your programs, too.\n\n       When we speak of free software, we are referring to freedom, not\n     price.  Our General Public Licenses are designed to make sure that you\n     have the freedom to distribute copies of free software (and charge for\n     them if you wish), that you receive source code or can get it if you\n     want it, that you can change the software or use pieces of it in new\n     free programs, and that you know you can do these things.\n\n       To protect your rights, we need to prevent others from denying you\n     these rights or asking you to surrender the rights.  Therefore, you have\n     certain responsibilities if you distribute copies of the software, or if\n     you modify it: responsibilities to respect the freedom of others.\n\n       For example, if you distribute copies of such a program, whether\n     gratis or for a fee, you must pass on to the recipients the same\n     freedoms that you received.  You must make sure that they, too, receive\n     or can get the source code.  And you must show them these terms so they\n     know their rights.\n\n       Developers that use the GNU GPL protect your rights with two steps:\n     (1) assert copyright on the software, and (2) offer you this License\n     giving you legal permission to copy, distribute and/or modify it.\n\n       For the developers' and authors' protection, the GPL clearly explains\n     that there is no warranty for this free software.  For both users' and\n     authors' sake, the GPL requires that modified versions be marked as\n     changed, so that their problems will not be attributed erroneously to\n     authors of previous versions.\n\n       Some devices are designed to deny users access to install or run\n     modified versions of the software inside them, although the manufacturer\n     can do so.  This is fundamentally incompatible with the aim of\n     protecting users' freedom to change the software.  The systematic\n     pattern of such abuse occurs in the area of products for individuals to\n     use, which is precisely where it is most unacceptable.  Therefore, we\n     have designed this version of the GPL to prohibit the practice for those\n     products.  If such problems arise substantially in other domains, we\n     stand ready to extend this provision to those domains in future versions\n     of the GPL, as needed to protect the freedom of users.\n\n       Finally, every program is threatened constantly by software patents.\n     States should not allow patents to restrict development and use of\n     software on general-purpose computers, but in those that do, we wish to\n     avoid the special danger that patents applied to a free program could\n     make it effectively proprietary.  To prevent this, the GPL assures that\n     patents cannot be used to render the program non-free.\n\n       The precise terms and conditions for copying, distribution and\n     modification follow.\n\n                            TERMS AND CONDITIONS\n\n       0. Definitions.\n\n       \"This License\" refers to version 3 of the GNU General Public License.\n\n       \"Copyright\" also means copyright-like laws that apply to other kinds of\n     works, such as semiconductor masks.\n\n       \"The Program\" refers to any copyrightable work licensed under this\n     License.  Each licensee is addressed as \"you\".  \"Licensees\" and\n     \"recipients\" may be individuals or organizations.\n\n       To \"modify\" a work means to copy from or adapt all or part of the work\n     in a fashion requiring copyright permission, other than the making of an\n     exact copy.  The resulting work is called a \"modified version\" of the\n     earlier work or a work \"based on\" the earlier work.\n\n       A \"covered work\" means either the unmodified Program or a work based\n     on the Program.\n\n       To \"propagate\" a work means to do anything with it that, without\n     permission, would make you directly or secondarily liable for\n     infringement under applicable copyright law, except executing it on a\n     computer or modifying a private copy.  Propagation includes copying,\n     distribution (with or without modification), making available to the\n     public, and in some countries other activities as well.\n\n       To \"convey\" a work means any kind of propagation that enables other\n     parties to make or receive copies.  Mere interaction with a user through\n     a computer network, with no transfer of a copy, is not conveying.\n\n       An interactive user interface displays \"Appropriate Legal Notices\"\n     to the extent that it includes a convenient and prominently visible\n     feature that (1) displays an appropriate copyright notice, and (2)\n     tells the user that there is no warranty for the work (except to the\n     extent that warranties are provided), that licensees may convey the\n     work under this License, and how to view a copy of this License.  If\n     the interface presents a list of user commands or options, such as a\n     menu, a prominent item in the list meets this criterion.\n\n       1. Source Code.\n\n       The \"source code\" for a work means the preferred form of the work\n     for making modifications to it.  \"Object code\" means any non-source\n     form of a work.\n\n       A \"Standard Interface\" means an interface that either is an official\n     standard defined by a recognized standards body, or, in the case of\n     interfaces specified for a particular programming language, one that\n     is widely used among developers working in that language.\n\n       The \"System Libraries\" of an executable work include anything, other\n     than the work as a whole, that (a) is included in the normal form of\n     packaging a Major Component, but which is not part of that Major\n     Component, and (b) serves only to enable use of the work with that\n     Major Component, or to implement a Standard Interface for which an\n     implementation is available to the public in source code form.  A\n     \"Major Component\", in this context, means a major essential component\n     (kernel, window system, and so on) of the specific operating system\n     (if any) on which the executable work runs, or a compiler used to\n     produce the work, or an object code interpreter used to run it.\n\n       The \"Corresponding Source\" for a work in object code form means all\n     the source code needed to generate, install, and (for an executable\n     work) run the object code and to modify the work, including scripts to\n     control those activities.  However, it does not include the work's\n     System Libraries, or general-purpose tools or generally available free\n     programs which are used unmodified in performing those activities but\n     which are not part of the work.  For example, Corresponding Source\n     includes interface definition files associated with source files for\n     the work, and the source code for shared libraries and dynamically\n     linked subprograms that the work is specifically designed to require,\n     such as by intimate data communication or control flow between those\n     subprograms and other parts of the work.\n\n       The Corresponding Source need not include anything that users\n     can regenerate automatically from other parts of the Corresponding\n     Source.\n\n       The Corresponding Source for a work in source code form is that\n     same work.\n\n       2. Basic Permissions.\n\n       All rights granted under this License are granted for the term of\n     copyright on the Program, and are irrevocable provided the stated\n     conditions are met.  This License explicitly affirms your unlimited\n     permission to run the unmodified Program.  The output from running a\n     covered work is covered by this License only if the output, given its\n     content, constitutes a covered work.  This License acknowledges your\n     rights of fair use or other equivalent, as provided by copyright law.\n\n       You may make, run and propagate covered works that you do not\n     convey, without conditions so long as your license otherwise remains\n     in force.  You may convey covered works to others for the sole purpose\n     of having them make modifications exclusively for you, or provide you\n     with facilities for running those works, provided that you comply with\n     the terms of this License in conveying all material for which you do\n     not control copyright.  Those thus making or running the covered works\n     for you must do so exclusively on your behalf, under your direction\n     and control, on terms that prohibit them from making any copies of\n     your copyrighted material outside their relationship with you.\n\n       Conveying under any other circumstances is permitted solely under\n     the conditions stated below.  Sublicensing is not allowed; section 10\n     makes it unnecessary.\n\n       3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n       No covered work shall be deemed part of an effective technological\n     measure under any applicable law fulfilling obligations under article\n     11 of the WIPO copyright treaty adopted on 20 December 1996, or\n     similar laws prohibiting or restricting circumvention of such\n     measures.\n\n       When you convey a covered work, you waive any legal power to forbid\n     circumvention of technological measures to the extent such circumvention\n     is effected by exercising rights under this License with respect to\n     the covered work, and you disclaim any intention to limit operation or\n     modification of the work as a means of enforcing, against the work's\n     users, your or third parties' legal rights to forbid circumvention of\n     technological measures.\n\n       4. Conveying Verbatim Copies.\n\n       You may convey verbatim copies of the Program's source code as you\n     receive it, in any medium, provided that you conspicuously and\n     appropriately publish on each copy an appropriate copyright notice;\n     keep intact all notices stating that this License and any\n     non-permissive terms added in accord with section 7 apply to the code;\n     keep intact all notices of the absence of any warranty; and give all\n     recipients a copy of this License along with the Program.\n\n       You may charge any price or no price for each copy that you convey,\n     and you may offer support or warranty protection for a fee.\n\n       5. Conveying Modified Source Versions.\n\n       You may convey a work based on the Program, or the modifications to\n     produce it from the Program, in the form of source code under the\n     terms of section 4, provided that you also meet all of these conditions:\n\n         a) The work must carry prominent notices stating that you modified\n         it, and giving a relevant date.\n\n         b) The work must carry prominent notices stating that it is\n         released under this License and any conditions added under section\n         7.  This requirement modifies the requirement in section 4 to\n         \"keep intact all notices\".\n\n         c) You must license the entire work, as a whole, under this\n         License to anyone who comes into possession of a copy.  This\n         License will therefore apply, along with any applicable section 7\n         additional terms, to the whole of the work, and all its parts,\n         regardless of how they are packaged.  This License gives no\n         permission to license the work in any other way, but it does not\n         invalidate such permission if you have separately received it.\n\n         d) If the work has interactive user interfaces, each must display\n         Appropriate Legal Notices; however, if the Program has interactive\n         interfaces that do not display Appropriate Legal Notices, your\n         work need not make them do so.\n\n       A compilation of a covered work with other separate and independent\n     works, which are not by their nature extensions of the covered work,\n     and which are not combined with it such as to form a larger program,\n     in or on a volume of a storage or distribution medium, is called an\n     \"aggregate\" if the compilation and its resulting copyright are not\n     used to limit the access or legal rights of the compilation's users\n     beyond what the individual works permit.  Inclusion of a covered work\n     in an aggregate does not cause this License to apply to the other\n     parts of the aggregate.\n\n       6. Conveying Non-Source Forms.\n\n       You may convey a covered work in object code form under the terms\n     of sections 4 and 5, provided that you also convey the\n     machine-readable Corresponding Source under the terms of this License,\n     in one of these ways:\n\n         a) Convey the object code in, or embodied in, a physical product\n         (including a physical distribution medium), accompanied by the\n         Corresponding Source fixed on a durable physical medium\n         customarily used for software interchange.\n\n         b) Convey the object code in, or embodied in, a physical product\n         (including a physical distribution medium), accompanied by a\n         written offer, valid for at least three years and valid for as\n         long as you offer spare parts or customer support for that product\n         model, to give anyone who possesses the object code either (1) a\n         copy of the Corresponding Source for all the software in the\n         product that is covered by this License, on a durable physical\n         medium customarily used for software interchange, for a price no\n         more than your reasonable cost of physically performing this\n         conveying of source, or (2) access to copy the\n         Corresponding Source from a network server at no charge.\n\n         c) Convey individual copies of the object code with a copy of the\n         written offer to provide the Corresponding Source.  This\n         alternative is allowed only occasionally and noncommercially, and\n         only if you received the object code with such an offer, in accord\n         with subsection 6b.\n\n         d) Convey the object code by offering access from a designated\n         place (gratis or for a charge), and offer equivalent access to the\n         Corresponding Source in the same way through the same place at no\n         further charge.  You need not require recipients to copy the\n         Corresponding Source along with the object code.  If the place to\n         copy the object code is a network server, the Corresponding Source\n         may be on a different server (operated by you or a third party)\n         that supports equivalent copying facilities, provided you maintain\n         clear directions next to the object code saying where to find the\n         Corresponding Source.  Regardless of what server hosts the\n         Corresponding Source, you remain obligated to ensure that it is\n         available for as long as needed to satisfy these requirements.\n\n         e) Convey the object code using peer-to-peer transmission, provided\n         you inform other peers where the object code and Corresponding\n         Source of the work are being offered to the general public at no\n         charge under subsection 6d.\n\n       A separable portion of the object code, whose source code is excluded\n     from the Corresponding Source as a System Library, need not be\n     included in conveying the object code work.\n\n       A \"User Product\" is either (1) a \"consumer product\", which means any\n     tangible personal property which is normally used for personal, family,\n     or household purposes, or (2) anything designed or sold for incorporation\n     into a dwelling.  In determining whether a product is a consumer product,\n     doubtful cases shall be resolved in favor of coverage.  For a particular\n     product received by a particular user, \"normally used\" refers to a\n     typical or common use of that class of product, regardless of the status\n     of the particular user or of the way in which the particular user\n     actually uses, or expects or is expected to use, the product.  A product\n     is a consumer product regardless of whether the product has substantial\n     commercial, industrial or non-consumer uses, unless such uses represent\n     the only significant mode of use of the product.\n\n       \"Installation Information\" for a User Product means any methods,\n     procedures, authorization keys, or other information required to install\n     and execute modified versions of a covered work in that User Product from\n     a modified version of its Corresponding Source.  The information must\n     suffice to ensure that the continued functioning of the modified object\n     code is in no case prevented or interfered with solely because\n     modification has been made.\n\n       If you convey an object code work under this section in, or with, or\n     specifically for use in, a User Product, and the conveying occurs as\n     part of a transaction in which the right of possession and use of the\n     User Product is transferred to the recipient in perpetuity or for a\n     fixed term (regardless of how the transaction is characterized), the\n     Corresponding Source conveyed under this section must be accompanied\n     by the Installation Information.  But this requirement does not apply\n     if neither you nor any third party retains the ability to install\n     modified object code on the User Product (for example, the work has\n     been installed in ROM).\n\n       The requirement to provide Installation Information does not include a\n     requirement to continue to provide support service, warranty, or updates\n     for a work that has been modified or installed by the recipient, or for\n     the User Product in which it has been modified or installed.  Access to a\n     network may be denied when the modification itself materially and\n     adversely affects the operation of the network or violates the rules and\n     protocols for communication across the network.\n\n       Corresponding Source conveyed, and Installation Information provided,\n     in accord with this section must be in a format that is publicly\n     documented (and with an implementation available to the public in\n     source code form), and must require no special password or key for\n     unpacking, reading or copying.\n\n       7. Additional Terms.\n\n       \"Additional permissions\" are terms that supplement the terms of this\n     License by making exceptions from one or more of its conditions.\n     Additional permissions that are applicable to the entire Program shall\n     be treated as though they were included in this License, to the extent\n     that they are valid under applicable law.  If additional permissions\n     apply only to part of the Program, that part may be used separately\n     under those permissions, but the entire Program remains governed by\n     this License without regard to the additional permissions.\n\n       When you convey a copy of a covered work, you may at your option\n     remove any additional permissions from that copy, or from any part of\n     it.  (Additional permissions may be written to require their own\n     removal in certain cases when you modify the work.)  You may place\n     additional permissions on material, added by you to a covered work,\n     for which you have or can give appropriate copyright permission.\n\n       Notwithstanding any other provision of this License, for material you\n     add to a covered work, you may (if authorized by the copyright holders of\n     that material) supplement the terms of this License with terms:\n\n         a) Disclaiming warranty or limiting liability differently from the\n         terms of sections 15 and 16 of this License; or\n\n         b) Requiring preservation of specified reasonable legal notices or\n         author attributions in that material or in the Appropriate Legal\n         Notices displayed by works containing it; or\n\n         c) Prohibiting misrepresentation of the origin of that material, or\n         requiring that modified versions of such material be marked in\n         reasonable ways as different from the original version; or\n\n         d) Limiting the use for publicity purposes of names of licensors or\n         authors of the material; or\n\n         e) Declining to grant rights under trademark law for use of some\n         trade names, trademarks, or service marks; or\n\n         f) Requiring indemnification of licensors and authors of that\n         material by anyone who conveys the material (or modified versions of\n         it) with contractual assumptions of liability to the recipient, for\n         any liability that these contractual assumptions directly impose on\n         those licensors and authors.\n\n       All other non-permissive additional terms are considered \"further\n     restrictions\" within the meaning of section 10.  If the Program as you\n     received it, or any part of it, contains a notice stating that it is\n     governed by this License along with a term that is a further\n     restriction, you may remove that term.  If a license document contains\n     a further restriction but permits relicensing or conveying under this\n     License, you may add to a covered work material governed by the terms\n     of that license document, provided that the further restriction does\n     not survive such relicensing or conveying.\n\n       If you add terms to a covered work in accord with this section, you\n     must place, in the relevant source files, a statement of the\n     additional terms that apply to those files, or a notice indicating\n     where to find the applicable terms.\n\n       Additional terms, permissive or non-permissive, may be stated in the\n     form of a separately written license, or stated as exceptions;\n     the above requirements apply either way.\n\n       8. Termination.\n\n       You may not propagate or modify a covered work except as expressly\n     provided under this License.  Any attempt otherwise to propagate or\n     modify it is void, and will automatically terminate your rights under\n     this License (including any patent licenses granted under the third\n     paragraph of section 11).\n\n       However, if you cease all violation of this License, then your\n     license from a particular copyright holder is reinstated (a)\n     provisionally, unless and until the copyright holder explicitly and\n     finally terminates your license, and (b) permanently, if the copyright\n     holder fails to notify you of the violation by some reasonable means\n     prior to 60 days after the cessation.\n\n       Moreover, your license from a particular copyright holder is\n     reinstated permanently if the copyright holder notifies you of the\n     violation by some reasonable means, this is the first time you have\n     received notice of violation of this License (for any work) from that\n     copyright holder, and you cure the violation prior to 30 days after\n     your receipt of the notice.\n\n       Termination of your rights under this section does not terminate the\n     licenses of parties who have received copies or rights from you under\n     this License.  If your rights have been terminated and not permanently\n     reinstated, you do not qualify to receive new licenses for the same\n     material under section 10.\n\n       9. Acceptance Not Required for Having Copies.\n\n       You are not required to accept this License in order to receive or\n     run a copy of the Program.  Ancillary propagation of a covered work\n     occurring solely as a consequence of using peer-to-peer transmission\n     to receive a copy likewise does not require acceptance.  However,\n     nothing other than this License grants you permission to propagate or\n     modify any covered work.  These actions infringe copyright if you do\n     not accept this License.  Therefore, by modifying or propagating a\n     covered work, you indicate your acceptance of this License to do so.\n\n       10. Automatic Licensing of Downstream Recipients.\n\n       Each time you convey a covered work, the recipient automatically\n     receives a license from the original licensors, to run, modify and\n     propagate that work, subject to this License.  You are not responsible\n     for enforcing compliance by third parties with this License.\n\n       An \"entity transaction\" is a transaction transferring control of an\n     organization, or substantially all assets of one, or subdividing an\n     organization, or merging organizations.  If propagation of a covered\n     work results from an entity transaction, each party to that\n     transaction who receives a copy of the work also receives whatever\n     licenses to the work the party's predecessor in interest had or could\n     give under the previous paragraph, plus a right to possession of the\n     Corresponding Source of the work from the predecessor in interest, if\n     the predecessor has it or can get it with reasonable efforts.\n\n       You may not impose any further restrictions on the exercise of the\n     rights granted or affirmed under this License.  For example, you may\n     not impose a license fee, royalty, or other charge for exercise of\n     rights granted under this License, and you may not initiate litigation\n     (including a cross-claim or counterclaim in a lawsuit) alleging that\n     any patent claim is infringed by making, using, selling, offering for\n     sale, or importing the Program or any portion of it.\n\n       11. Patents.\n\n       A \"contributor\" is a copyright holder who authorizes use under this\n     License of the Program or a work on which the Program is based.  The\n     work thus licensed is called the contributor's \"contributor version\".\n\n       A contributor's \"essential patent claims\" are all patent claims\n     owned or controlled by the contributor, whether already acquired or\n     hereafter acquired, that would be infringed by some manner, permitted\n     by this License, of making, using, or selling its contributor version,\n     but do not include claims that would be infringed only as a\n     consequence of further modification of the contributor version.  For\n     purposes of this definition, \"control\" includes the right to grant\n     patent sublicenses in a manner consistent with the requirements of\n     this License.\n\n       Each contributor grants you a non-exclusive, worldwide, royalty-free\n     patent license under the contributor's essential patent claims, to\n     make, use, sell, offer for sale, import and otherwise run, modify and\n     propagate the contents of its contributor version.\n\n       In the following three paragraphs, a \"patent license\" is any express\n     agreement or commitment, however denominated, not to enforce a patent\n     (such as an express permission to practice a patent or covenant not to\n     sue for patent infringement).  To \"grant\" such a patent license to a\n     party means to make such an agreement or commitment not to enforce a\n     patent against the party.\n\n       If you convey a covered work, knowingly relying on a patent license,\n     and the Corresponding Source of the work is not available for anyone\n     to copy, free of charge and under the terms of this License, through a\n     publicly available network server or other readily accessible means,\n     then you must either (1) cause the Corresponding Source to be so\n     available, or (2) arrange to deprive yourself of the benefit of the\n     patent license for this particular work, or (3) arrange, in a manner\n     consistent with the requirements of this License, to extend the patent\n     license to downstream recipients.  \"Knowingly relying\" means you have\n     actual knowledge that, but for the patent license, your conveying the\n     covered work in a country, or your recipient's use of the covered work\n     in a country, would infringe one or more identifiable patents in that\n     country that you have reason to believe are valid.\n\n       If, pursuant to or in connection with a single transaction or\n     arrangement, you convey, or propagate by procuring conveyance of, a\n     covered work, and grant a patent license to some of the parties\n     receiving the covered work authorizing them to use, propagate, modify\n     or convey a specific copy of the covered work, then the patent license\n     you grant is automatically extended to all recipients of the covered\n     work and works based on it.\n\n       A patent license is \"discriminatory\" if it does not include within\n     the scope of its coverage, prohibits the exercise of, or is\n     conditioned on the non-exercise of one or more of the rights that are\n     specifically granted under this License.  You may not convey a covered\n     work if you are a party to an arrangement with a third party that is\n     in the business of distributing software, under which you make payment\n     to the third party based on the extent of your activity of conveying\n     the work, and under which the third party grants, to any of the\n     parties who would receive the covered work from you, a discriminatory\n     patent license (a) in connection with copies of the covered work\n     conveyed by you (or copies made from those copies), or (b) primarily\n     for and in connection with specific products or compilations that\n     contain the covered work, unless you entered into that arrangement,\n     or that patent license was granted, prior to 28 March 2007.\n\n       Nothing in this License shall be construed as excluding or limiting\n     any implied license or other defenses to infringement that may\n     otherwise be available to you under applicable patent law.\n\n       12. No Surrender of Others' Freedom.\n\n       If conditions are imposed on you (whether by court order, agreement or\n     otherwise) that contradict the conditions of this License, they do not\n     excuse you from the conditions of this License.  If you cannot convey a\n     covered work so as to satisfy simultaneously your obligations under this\n     License and any other pertinent obligations, then as a consequence you may\n     not convey it at all.  For example, if you agree to terms that obligate you\n     to collect a royalty for further conveying from those to whom you convey\n     the Program, the only way you could satisfy both those terms and this\n     License would be to refrain entirely from conveying the Program.\n\n       13. Use with the GNU Affero General Public License.\n\n       Notwithstanding any other provision of this License, you have\n     permission to link or combine any covered work with a work licensed\n     under version 3 of the GNU Affero General Public License into a single\n     combined work, and to convey the resulting work.  The terms of this\n     License will continue to apply to the part which is the covered work,\n     but the special requirements of the GNU Affero General Public License,\n     section 13, concerning interaction through a network will apply to the\n     combination as such.\n\n       14. Revised Versions of this License.\n\n       The Free Software Foundation may publish revised and/or new versions of\n     the GNU General Public License from time to time.  Such new versions will\n     be similar in spirit to the present version, but may differ in detail to\n     address new problems or concerns.\n\n       Each version is given a distinguishing version number.  If the\n     Program specifies that a certain numbered version of the GNU General\n     Public License \"or any later version\" applies to it, you have the\n     option of following the terms and conditions either of that numbered\n     version or of any later version published by the Free Software\n     Foundation.  If the Program does not specify a version number of the\n     GNU General Public License, you may choose any version ever published\n     by the Free Software Foundation.\n\n       If the Program specifies that a proxy can decide which future\n     versions of the GNU General Public License can be used, that proxy's\n     public statement of acceptance of a version permanently authorizes you\n     to choose that version for the Program.\n\n       Later license versions may give you additional or different\n     permissions.  However, no additional obligations are imposed on any\n     author or copyright holder as a result of your choosing to follow a\n     later version.\n\n       15. Disclaimer of Warranty.\n\n       THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\n     APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\n     HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\n     OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\n     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n     PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\n     IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\n     ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n       16. Limitation of Liability.\n\n       IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n     WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\n     THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\n     GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\n     USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\n     DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\n     PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\n     EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\n     SUCH DAMAGES.\n\n       17. Interpretation of Sections 15 and 16.\n\n       If the disclaimer of warranty and limitation of liability provided\n     above cannot be given local legal effect according to their terms,\n     reviewing courts shall apply local law that most closely approximates\n     an absolute waiver of all civil liability in connection with the\n     Program, unless a warranty or assumption of liability accompanies a\n     copy of the Program in return for a fee.\n\n                          END OF TERMS AND CONDITIONS\n\n                 How to Apply These Terms to Your New Programs\n\n       If you develop a new program, and you want it to be of the greatest\n     possible use to the public, the best way to achieve this is to make it\n     free software which everyone can redistribute and change under these terms.\n\n       To do so, attach the following notices to the program.  It is safest\n     to attach them to the start of each source file to most effectively\n     state the exclusion of warranty; and each file should have at least\n     the \"copyright\" line and a pointer to where the full notice is found.\n\n         <one line to give the program's name and a brief idea of what it does.>\n         Copyright (C) <year>  <name of author>\n\n         This program is free software: you can redistribute it and/or modify\n         it under the terms of the GNU General Public License as published by\n         the Free Software Foundation, either version 3 of the License, or\n         (at your option) any later version.\n\n         This program is distributed in the hope that it will be useful,\n         but WITHOUT ANY WARRANTY; without even the implied warranty of\n         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n         GNU General Public License for more details.\n\n         You should have received a copy of the GNU General Public License\n         along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n     Also add information on how to contact you by electronic and paper mail.\n\n       If the program does terminal interaction, make it output a short\n     notice like this when it starts in an interactive mode:\n\n         <program>  Copyright (C) <year>  <name of author>\n         This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n         This is free software, and you are welcome to redistribute it\n         under certain conditions; type `show c' for details.\n\n     The hypothetical commands `show w' and `show c' should show the appropriate\n     parts of the General Public License.  Of course, your program's commands\n     might be different; for a GUI interface, you would use an \"about box\".\n\n       You should also get your employer (if you work as a programmer) or school,\n     if any, to sign a \"copyright disclaimer\" for the program, if necessary.\n     For more information on this, and how to apply and follow the GNU GPL, see\n     <http://www.gnu.org/licenses/>.\n\n       The GNU General Public License does not permit incorporating your program\n     into proprietary programs.  If your program is a subroutine library, you\n     may consider it more useful to permit linking proprietary applications with\n     the library.  If this is what you want to do, use the GNU Lesser General\n     Public License instead of this License.  But first, please read\n     <http://www.gnu.org/philosophy/why-not-lgpl.html>.\n\n\u001f\nFile: rgel.info,  Node: Index,  Prev: License,  Up: Top\n\nIndex\n*****\n\n\u0000\b[index\u0000\b]\n* Menu:\n\n* compilation-next-error (command):      Navigation.          (line   8)\n* compilation-next-file (command):       Navigation.          (line  36)\n* compilation-previous-error (command):  Navigation.          (line  12)\n* compilation-previous-file (command):   Navigation.          (line  40)\n* compile-goto-error (command):          Navigation.          (line  44)\n* next-error-no-select (command):        Navigation.          (line  16)\n* previous-error-no-select (command):    Navigation.          (line  21)\n* rg (command):                          Interactive search.  (line   9)\n* rg-align-column-number-field-length (customize option): Position numbers alignment.\n                                                              (line  33)\n* rg-align-line-column-separator (customize option): Position numbers alignment.\n                                                              (line  37)\n* rg-align-line-number-field-length (customize option): Position numbers alignment.\n                                                              (line  29)\n* rg-align-position-content-separator (customize option): Position numbers alignment.\n                                                              (line  42)\n* rg-align-position-numbers (customize option): Position numbers alignment.\n                                                              (line  24)\n* rg-back-history (command):             History navigation.  (line  10)\n* rg-buffer-name (customize option):     Customization.       (line 128)\n* rg-column-number-face (customize option): Results buffer<2>.\n                                                              (line  40)\n* rg-command-line-flags (customize option): Customization.    (line  68)\n* rg-context-face (customize option):    Results buffer<2>.   (line  14)\n* rg-custom-type-aliases (customize option): Customization.   (line  29)\n* rg-default-alias-fallback (customize option): Customization.\n                                                              (line  62)\n* rg-define-search (function):           Configuration macros.\n                                                              (line  28)\n* rg-define-toggle (function):           Configuration macros.\n                                                              (line   6)\n* rg-dwim (command):                     Do what I mean.      (line  35)\n* rg-dwim-current-dir (command):         Do what I mean.      (line  23)\n* rg-dwim-current-file (command):        Do what I mean.      (line  27)\n* rg-dwim-project-dir (command):         Do what I mean.      (line  19)\n* rg-enable-default-bindings (function): Configuration functions.\n                                                              (line   6)\n* rg-enable-menu (function):             Configuration functions.\n                                                              (line  13)\n* rg-error-face (customize option):      Results buffer<2>.   (line  10)\n* rg-executable (customize option):      Customization.       (line  11)\n* rg-executable-per-connection (customize option): Customization.\n                                                              (line  21)\n* rg-file-tag-face (customize option):   Results buffer<2>.   (line  32)\n* rg-filename-face (customize option):   Results buffer<2>.   (line  28)\n* rg-filter-hook (customize option):     Hooks.               (line  13)\n* rg-finish-functions (customize option): Hooks.              (line   6)\n* rg-forward-history (command):          History navigation.  (line  14)\n* rg-group-result (customize option):    Customization.       (line  74)\n* rg-hide-command (customize option):    Customization.       (line 103)\n* rg-ignore-case (customize option):     Customization.       (line  86)\n* rg-ignore-ripgreprc (customize option): Customization.      (line 146)\n* rg-info-face (customize option):       Results buffer<2>.   (line  19)\n* rg-keymap-prefix (customize option):   Customization.       (line 109)\n* rg-kill-saved-searches (command):      Search management.   (line  43)\n* rg-line-number-face (customize option): Results buffer<2>.  (line  36)\n* rg-list-searches (command):            Search management.   (line  38)\n* rg-literal (command):                  Interactive search.  (line  23)\n* rg-literal-face (customize option):    Header line.         (line  14)\n* rg-match-face (customize option):      Results buffer<2>.   (line   6)\n* rg-match-position-face (customize option): Results buffer<2>.\n                                                              (line  44)\n* rg-menu (command):                     Refine search.       (line  51)\n* rg-menu-transient-insert (function):   Customizing the menu.\n                                                              (line  33)\n* rg-mode-hook (customize option):       Hooks.               (line  19)\n* rg-next-file (command):                Navigation.          (line  26)\n* rg-prev-file (command):                Navigation.          (line  31)\n* rg-prioritized-type-aliases (customize option): Customization.\n                                                              (line  50)\n* rg-project (command):                  Project search.      (line  17)\n* rg-recompile (command):                Refine search.       (line  34)\n* rg-regexp-face (customize option):     Header line.         (line  18)\n* rg-rerun-change-dir (command):         Refine search.       (line  10)\n* rg-rerun-change-files (command):       Refine search.       (line  14)\n* rg-rerun-change-literal (command):     Refine search.       (line  18)\n* rg-rerun-change-regexp (command):      Refine search.       (line  23)\n* rg-rerun-toggle-case (command):        Refine search.       (line  38)\n* rg-rerun-toggle-ignore (command):      Refine search.       (line  43)\n* rg-save-search (command):              Search management.   (line  10)\n* rg-save-search-as-name (command):      Search management.   (line  22)\n* rg-show-columns (customize option):    Customization.       (line  82)\n* rg-show-header (customize option):     Customization.       (line 122)\n* rg-toggle-off-face (customize option): Header line.         (line  10)\n* rg-toggle-on-face (customize option):  Header line.         (line   6)\n* rg-use-old-defaults (function):        Configuration functions.\n                                                              (line  19)\n* rg-use-transient-menu (customize option): Customization.    (line 115)\n* rg-warning-face (customize option):    Results buffer<2>.   (line  24)\n* wgrep-change-to-wgrep-mode (command):  Edit and apply wgrep.\n                                                              (line  10)\n\n\n\u001f\nTag Table:\nNode: Top317\nRef: index doc496\nRef: 0496\nNode: Usage1496\nRef: usage doc1573\nRef: 11573\nRef: usage rg-manual1573\nRef: 21573\nRef: usage usage1573\nRef: 31573\nNode: Installation1694\nRef: usage id11764\nRef: 41764\nRef: usage installation1764\nRef: 51764\nNode: Searching5722\nRef: usage id25815\nRef: 85815\nRef: usage searching5815\nRef: 95815\nNode: Case sensitivity6733\nRef: usage case-sensitivity6820\nRef: b6820\nNode: Interactive search7513\nRef: usage basic-search7623\nRef: d7623\nRef: usage interactive-search7623\nRef: e7623\nRef: usage command-rg7790\nRef: f7790\nRef: usage command-rg-literal8463\nRef: 128463\nNode: Project search8839\nRef: usage id38947\nRef: 138947\nRef: usage project-search8947\nRef: 148947\nRef: usage command-rg-project9618\nRef: 159618\nNode: Do what I mean9892\nRef: usage do-what-i-mean9996\nRef: 169996\nRef: usage id49996\nRef: 179996\nRef: usage command-rg-dwim-project-dir10739\nRef: 1910739\nRef: usage command-rg-dwim-current-dir10842\nRef: 1a10842\nRef: usage command-rg-dwim-current-file10937\nRef: 1b10937\nRef: usage command-rg-dwim11343\nRef: 1c11343\nNode: Isearch search11649\nRef: usage id511756\nRef: 1d11756\nRef: usage isearch-search11756\nRef: 611756\nNode: File type aliases12301\nRef: usage file-type-aliases12402\nRef: 1012402\nRef: usage id612402\nRef: 1e12402\nNode: The menu13765\nRef: usage id713843\nRef: 2013843\nRef: usage the-menu13843\nRef: a13843\nNode: Results buffer15992\nRef: usage id816090\nRef: 2416090\nRef: usage results-buffer16090\nRef: 2316090\nNode: Navigation16737\nRef: usage navigation16818\nRef: 2516818\nRef: usage command-compilation-next-error16910\nRef: 2616910\nRef: usage command-compilation-previous-error16997\nRef: 2716997\nRef: usage command-next-error-no-select17092\nRef: 2817092\nRef: usage command-previous-error-no-select17236\nRef: 2917236\nRef: usage command-rg-next-file17388\nRef: 2a17388\nRef: usage command-rg-prev-file17543\nRef: 2c17543\nRef: usage command-compilation-next-file17702\nRef: 2d17702\nRef: usage command-compilation-previous-file17789\nRef: 2e17789\nRef: usage command-compile-goto-error17879\nRef: 2f17879\nNode: Refine search18120\nRef: usage refine-search18234\nRef: 3018234\nRef: usage command-rg-rerun-change-dir18451\nRef: 3118451\nRef: usage command-rg-rerun-change-files18542\nRef: 3218542\nRef: usage command-rg-rerun-change-literal18638\nRef: 3318638\nRef: usage command-rg-rerun-change-regexp18766\nRef: 3418766\nRef: usage command-rg-recompile19205\nRef: 3519205\nRef: usage command-rg-rerun-toggle-case19306\nRef: 3619306\nRef: usage command-rg-rerun-toggle-ignore19459\nRef: 3719459\nRef: usage command-rg-menu19731\nRef: 3919731\nNode: Full command line search19834\nRef: usage full-command-line-search19956\nRef: 1119956\nRef: usage id919956\nRef: 3a19956\nNode: History navigation20480\nRef: usage history-navigation20609\nRef: 3b20609\nRef: usage id1020609\nRef: 3c20609\nRef: usage command-rg-back-history20855\nRef: 3d20855\nRef: usage command-rg-forward-history20931\nRef: 3e20931\nNode: Edit and apply wgrep21177\nRef: usage edit-and-apply21273\nRef: 3f21273\nRef: usage edit-and-apply-wgrep21273\nRef: 4021273\nRef: usage command-wgrep-change-to-wgrep-mode21495\nRef: 4121495\nNode: Search management21741\nRef: usage id1221847\nRef: 4221847\nRef: usage search-management21847\nRef: 4321847\nRef: usage command-rg-save-search22088\nRef: 4422088\nRef: usage command-rg-save-search-as-name22531\nRef: 4522531\nRef: usage command-rg-list-searches23272\nRef: 4723272\nRef: usage command-rg-kill-saved-searches23427\nRef: 4823427\nNode: Multi line search23928\nRef: usage id1324011\nRef: 4924011\nRef: usage multi-line-search24011\nRef: 4a24011\nNode: Configuration24698\nRef: configuration doc24782\nRef: 4c24782\nRef: configuration configuration24782\nRef: 4d24782\nNode: Customization24964\nRef: configuration customization25039\nRef: 4e25039\nRef: configuration id125039\nRef: 4f25039\nRef: configuration option-rg-executable25230\nRef: 5025230\nRef: configuration option-rg-executable-per-connection25791\nRef: 5125791\nRef: configuration option-rg-custom-type-aliases26162\nRef: 1f26162\nRef: configuration option-rg-prioritized-type-aliases26824\nRef: 5226824\nRef: configuration option-rg-default-alias-fallback27204\nRef: 1827204\nRef: configuration option-rg-command-line-flags27455\nRef: 4b27455\nRef: configuration option-rg-group-result27678\nRef: 2b27678\nRef: configuration option-rg-show-columns28020\nRef: 5328020\nRef: configuration option-rg-ignore-case28127\nRef: c28127\nRef: configuration option-rg-hide-command28767\nRef: 5428767\nRef: configuration option-rg-keymap-prefix29021\nRef: 2129021\nRef: configuration option-rg-use-transient-menu29253\nRef: 5529253\nRef: configuration option-rg-show-header29459\nRef: 5629459\nRef: configuration option-rg-buffer-name29667\nRef: 4629667\nRef: configuration option-rg-ignore-ripgreprc30380\nRef: 730380\nNode: Position numbers alignment31015\nRef: configuration id231089\nRef: 5731089\nRef: configuration position-numbers-alignment31089\nRef: 5831089\nRef: configuration option-rg-align-position-numbers31696\nRef: 5931696\nRef: configuration option-rg-align-line-number-field-length31853\nRef: 5a31853\nRef: configuration option-rg-align-column-number-field-length31963\nRef: 5b31963\nRef: configuration option-rg-align-line-column-separator32077\nRef: 5c32077\nRef: configuration option-rg-align-position-content-separator32256\nRef: 5d32256\nNode: Faces32457\nRef: configuration faces32564\nRef: 5e32564\nNode: Results buffer<2>32767\nRef: configuration results-buffer32844\nRef: 5f32844\nRef: configuration option-rg-match-face32887\nRef: 6032887\nRef: configuration option-rg-error-face32978\nRef: 6132978\nRef: configuration option-rg-context-face33094\nRef: 6233094\nRef: configuration option-rg-info-face33249\nRef: 6333249\nRef: configuration option-rg-warning-face33411\nRef: 6433411\nRef: configuration option-rg-filename-face33533\nRef: 6533533\nRef: configuration option-rg-file-tag-face33640\nRef: 6633640\nRef: configuration option-rg-line-number-face33760\nRef: 6733760\nRef: configuration option-rg-column-number-face33860\nRef: 6833860\nRef: configuration option-rg-match-position-face33966\nRef: 6933966\nNode: Header line34185\nRef: configuration header-line34262\nRef: 6a34262\nRef: configuration header-line-config34262\nRef: 6b34262\nRef: configuration option-rg-toggle-on-face34299\nRef: 6c34299\nRef: configuration option-rg-toggle-off-face34410\nRef: 6d34410\nRef: configuration option-rg-literal-face34520\nRef: 6e34520\nRef: configuration option-rg-regexp-face34644\nRef: 6f34644\nNode: Configuration functions34773\nRef: configuration configuration-functions34872\nRef: 7034872\nRef: configuration id334872\nRef: 7134872\nRef: configuration function-rg-enable-default-bindings34929\nRef: 7234929\nRef: configuration function-rg-enable-menu35275\nRef: 7335275\nRef: configuration function-rg-use-old-defaults35523\nRef: 7435523\nNode: Hooks35816\nRef: configuration hooks35930\nRef: 7535930\nRef: configuration id435930\nRef: 7635930\nRef: configuration option-rg-finish-functions35951\nRef: 7735951\nRef: configuration option-rg-filter-hook36186\nRef: 7836186\nRef: configuration option-rg-mode-hook36429\nRef: 7936429\nNode: Configuration macros36521\nRef: configuration configuration-macros36630\nRef: 7a36630\nRef: configuration id536630\nRef: 7b36630\nRef: configuration function-rg-define-toggle36681\nRef: 3836681\nRef: configuration function-rg-define-search37590\nRef: 2237590\nNode: Use with evil-mode40589\nRef: configuration use-with-evil-mode40713\nRef: 7c40713\nNode: Customizing the menu41687\nRef: configuration customizing-the-menu41782\nRef: 7d41782\nRef: configuration id641782\nRef: 7e41782\nRef: configuration function-rg-menu-transient-insert42818\nRef: 7f42818\nNode: Contribute43441\nRef: contribute doc43527\nRef: 8043527\nRef: contribute contribute43527\nRef: 8143527\nNode: Pull requests43833\nRef: contribute id143906\nRef: 8243906\nRef: contribute pull-requests43906\nRef: 8343906\nNode: Docker44712\nRef: contribute docker44799\nRef: 8444799\nRef: contribute id244799\nRef: 8544799\nNode: Tests45769\nRef: contribute id345856\nRef: 8645856\nRef: contribute tests45856\nRef: 8745856\nNode: Setup46226\nRef: contribute setup46287\nRef: 8846287\nRef: contribute tests-setup46287\nRef: 8946287\nNode: Running46463\nRef: contribute running46524\nRef: 8a46524\nRef: contribute tests-running46524\nRef: 8b46524\nNode: Documentation46805\nRef: contribute documentation46877\nRef: 8c46877\nRef: contribute id446877\nRef: 8d46877\nNode: Setup<2>47597\nRef: contribute documentation-setup47670\nRef: 8e47670\nRef: contribute id547670\nRef: 8f47670\nNode: Building47910\nRef: contribute building47983\nRef: 9047983\nRef: contribute documentation-building47983\nRef: 9147983\nNode: License48288\nRef: index id148366\nRef: 9248366\nRef: index license48366\nRef: 9348366\nNode: GNU General Public License48898\nRef: gpl doc48966\nRef: 9548966\nRef: gpl gnu-general-public-license48966\nRef: 9648966\nRef: gpl gpl49029\nRef: 9449029\nNode: Index86942\n\u001f\nEnd Tag Table\n\n\u001f\nLocal Variables:\ncoding: utf-8\nEnd:\n"
  },
  {
    "path": "test/data/bar.baz",
    "content": "hello\nHello\nhellO\n"
  },
  {
    "path": "test/data/bar.el",
    "content": "hello\nHello\nhellO\n"
  },
  {
    "path": "test/data/context.el",
    "content": "context1\ncontext2\ncontext3\ncontext4\namid context\ncontext5\ncontext6\ncontext7\ncontext8\namid context\ncontext9\ncontext10\ncontext11\ncontext12\namid context\ncontext13\ncontext14\ncontext15\ncontext16\n"
  },
  {
    "path": "test/data/dirlocals/.dir-locals.el",
    "content": "((nil . ((rg-buffer-name . \"from dir locals\"))))\n"
  },
  {
    "path": "test/data/foo.baz",
    "content": "hello\nHello\nhellO\n"
  },
  {
    "path": "test/data/foo.el",
    "content": "hello\nHello\nhellO\n"
  },
  {
    "path": "test/data/limenu.el",
    "content": "imenu\n"
  },
  {
    "path": "test/package-bootstrap.el",
    "content": ";;; package-bootstrap.el --- rg.el: Helper for package install test\n\n;; Copyright (C) 2017 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;; This bootstraps package.el with a temporary package dir in\n;; /tmp/${PKG_FULL_NAME}-elpa to test package installation in a clean\n;; environment.\n\n;;; Code:\n\n(require 'package)\n\n(defvar pkg_name (getenv \"PKG_FULL_NAME\"))\n\n(setq package-user-dir (concat \"/tmp/\" pkg_name \"-elpa\"))\n(add-to-list 'package-archives '(\"melpa\" . \"http://melpa.org/packages/\") t)\n(package-initialize)\n(package-refresh-contents)\n"
  },
  {
    "path": "test/rg-header.el-test.el",
    "content": "(require 'cl-lib)\n\n(defvar rg-unit/long-search-pattern \"everything everywhere all at once\")\n\n;;; Mocks.\n\n(cl-defmacro rg-unit/mock-truncation-predicate ((&key max predicate) &rest body)\n  \"Execute BODY with truncation predicate mocked by PREDICATE.\n\nMAX is the value `rg-header-max-search-string-length' will be set to.\"\n  (declare (indent defun))\n  `(cl-letf* ((rg-header-max-search-string-length ,max)\n              ((symbol-function 'rg-header-truncates-p) #',predicate))\n     ,@body))\n\n(cl-defmacro rg-unit/mock-rg-cur-search-pattern ((&key do-return) &rest body)\n  \"Execute BODY with `rg-cur-search-pattern' mocked.\n\nInstead DO-RETURN will be returned when the function is called.\"\n  (declare (indent defun))\n\n  `(cl-letf* (((symbol-function 'rg-cur-search-pattern) (lambda (&rest _) ,do-return)))\n     ,@body))\n\n;;; Tests.\n\n(ert-deftest rg-unit/header-truncation-predicate ()\n  \"Test `rg-header-truncates-p'.\"\n\n  ;; Not set.\n  (let ((rg-header-max-search-string-length nil))\n\n    (should-not (rg-header-truncates-p rg-unit/long-search-pattern)))\n\n  ;; Erroneous value.\n  (let ((rg-header-max-search-string-length 'none))\n\n    (should-not (rg-header-truncates-p rg-unit/long-search-pattern)))\n\n  ;; The length of the string passed.\n  (let ((rg-header-max-search-string-length (length rg-unit/long-search-pattern)))\n\n    (should-not (rg-header-truncates-p rg-unit/long-search-pattern)))\n\n  ;; One below string length.\n  (let ((rg-header-max-search-string-length (1- (length rg-unit/long-search-pattern))))\n\n    (should (rg-header-truncates-p rg-unit/long-search-pattern)))\n\n  ;; At 0.\n  (let ((rg-header-max-search-string-length 0))\n\n    (should (rg-header-truncates-p rg-unit/long-search-pattern)))\n\n  ;; Below 0.\n  (let ((rg-header-max-search-string-length -1))\n\n    (should (rg-header-truncates-p rg-unit/long-search-pattern))))\n\n\n(ert-deftest rg-unit/search-pattern-truncation-in-header ()\n  \"Tests `rg-header-truncate-search-pattern'.\"\n  ;; When predicate is true.\n  (let ((ellipsis-len (length (rg-truncate-string-ellipsis))))\n    (rg-unit/mock-truncation-predicate (:max 11 :predicate always)\n      (should (string=\n               (concat (substring \"everything\" 0 (- 11 ellipsis-len)) (rg-truncate-string-ellipsis))\n               (rg-header-truncate-search-pattern rg-unit/long-search-pattern))))\n\n    (rg-unit/mock-truncation-predicate (:max 5 :predicate always)\n      (should (string=\n               (concat (substring \"ever\" 0 (- 5 ellipsis-len)) (rg-truncate-string-ellipsis))\n               (rg-header-truncate-search-pattern rg-unit/long-search-pattern))))\n\n    (rg-unit/mock-truncation-predicate (:max (length rg-unit/long-search-pattern) :predicate always)\n      (should (string=\n               \"everything everywhere all at once\"\n               (rg-header-truncate-search-pattern rg-unit/long-search-pattern))))\n\n    ;; When predicate is false.\n    (rg-unit/mock-truncation-predicate (:max 11 :predicate ignore)\n      (should (string=\n               \"everything everywhere all at once\"\n               (rg-header-truncate-search-pattern rg-unit/long-search-pattern))))\n\n    (rg-unit/mock-truncation-predicate (:predicate ignore)\n      (should (string=\n               \"everything everywhere all at once\"\n               (rg-header-truncate-search-pattern rg-unit/long-search-pattern))))))\n\n(ert-deftest rg-unit/search-help-for-header ()\n  \"Tests `rg-header-search-help'.\"\n  (rg-unit/mock-rg-cur-search-pattern (:do-return \"this is the full string\")\n\n    (rg-unit/mock-truncation-predicate (:predicate always)\n      (should (string= \"Change search string: this is the full string\" (rg-header-search-help))))\n\n    (rg-unit/mock-truncation-predicate (:predicate ignore)\n      (should (string= \"Change search string\" (rg-header-search-help))))))\n"
  },
  {
    "path": "test/rg-history.el-test.el",
    "content": ";;; rg-history.el-test.el --- Tests for rg-history.el -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;; Tests for search history navigation.\n\n;;; Code:\n\n\n\f\n;; Unit tests\n\n(ert-deftest rg-unit/history-navigation ()\n  \"Testing the history data structure for navigation.\"\n  (let ((instance (rg-history-create)))\n    (should (equal (rg-history-back instance) nil))\n    (rg-history-push 'search1 instance)\n    (rg-history-push 'search2 instance)\n    (rg-history-push 'search3 instance)\n    (should (equal (rg-history-forward instance) nil))\n    (should (equal (rg-history-back instance) 'search2))\n    (should (equal (rg-history-back instance) 'search1))\n    (should (equal (rg-history-back instance) nil))\n    (should (equal (rg-history-forward instance) 'search2))\n    (should (equal (rg-history-forward instance) 'search3))\n    (should (equal (rg-history-forward instance) nil))))\n\n(ert-deftest rg-unit/history-new-search ()\n  \"Testing the history data structure behavior when inserting new\nsearch after moving in history.\"\n  (let ((instance (rg-history-create)))\n    (should (equal (rg-history-back instance) nil))\n    (rg-history-push 'search1 instance)\n    (rg-history-push 'search2 instance)\n    (rg-history-push 'search3 instance)\n    (should (equal (rg-history-forward instance) nil))\n    (should (equal (rg-history-back instance) 'search2))\n    (rg-history-push 'search4 instance)\n    (should (equal (rg-history-forward instance) nil))\n    (should (equal (rg-history-back instance) 'search2))\n    (should (equal (rg-history-back instance) 'search1))\n    (should (equal (rg-history-back instance) nil))))\n\n\f\n;; Integration tests\n\n(ert-deftest rg-integration/history ()\n  \"Verify that simple history navigation works.\"\n  :tags '(need-rg)\n  (rg-run-and-wait #'rg-run\n                   \"foo\" \"all\" (concat default-directory \"test/data\"))\n  (rg-run-and-wait #'rg-run\n                   \"bar\" \"all\" (concat default-directory \"test/data\"))\n  (rg-run-and-wait #'rg-run\n                   \"baz\" \"all\" (concat default-directory \"test/data\"))\n  (with-current-buffer (rg-buffer-name)\n     (rg-run-and-wait #'rg-back-history)\n     (should (equal (rg-search-pattern rg-cur-search) \"bar\"))\n     (rg-run-and-wait #'rg-back-history)\n     (should (equal (rg-search-pattern rg-cur-search) \"foo\"))\n     (rg-run-and-wait #'rg-forward-history)\n     (should (equal (rg-search-pattern rg-cur-search) \"bar\"))\n     (rg-run-and-wait #'rg-forward-history)\n     (should (equal (rg-search-pattern rg-cur-search) \"baz\"))))\n\n(provide 'rg-history.el-test)\n\n;;; rg-history.el-test.el ends here\n"
  },
  {
    "path": "test/rg-isearch.el-test.el",
    "content": ";;; rg-isearch.el-test.el --- rg-isearch.el tests -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2020 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;;; Code:\n\n(ert-deftest rg-unit/isearch-current-file ()\n  \"Test `rg-isearch-current-file'.\"\n  (cl-letf* ((called-pattern nil)\n             (called-literal nil)\n             (called-files nil)\n             (called-dir nil)\n             ((symbol-function #'rg-run)\n              (lambda (pattern files dir &optional literal &rest _)\n                (setq called-pattern pattern)\n                (setq called-literal literal)\n                (setq called-files files)\n                (setq called-dir dir))))\n    (find-file \"test/data/bar.el\")\n    (let ((isearch-string \"test\"))\n      (rg-isearch-current-file)\n      (should (equal called-pattern \"test\"))\n      (should (eq called-literal t))\n      (should (equal called-files \"bar.el\"))\n      (should (equal (expand-file-name called-dir) (expand-file-name default-directory))))))\n\n\n(ert-deftest rg-unit/isearch-current-dir ()\n  \"Test `rg-isearch-current-dir'.\"\n  (cl-letf* ((called-pattern nil)\n             (called-literal nil)\n             (called-files nil)\n             (called-dir nil)\n             ((symbol-function #'rg-run)\n              (lambda (pattern files dir &optional literal &rest _)\n                (setq called-pattern pattern)\n                (setq called-literal literal)\n                (setq called-files files)\n                (setq called-dir dir))))\n    (find-file \"test/data/bar.el\")\n    (let ((isearch-string \"test\"))\n      (rg-isearch-current-dir)\n      (should (equal called-pattern \"test\"))\n      (should (eq called-literal t))\n      (should (equal called-files \"elisp\"))\n      (should (equal (expand-file-name called-dir) (expand-file-name default-directory))))))\n\n(ert-deftest rg-unit/isearch-project ()\n  \"Test `rg-isearch-project'.\"\n  (cl-letf* ((called-pattern nil)\n             (called-literal nil)\n             (called-files nil)\n             (called-dir nil)\n             (project-dir (expand-file-name default-directory))\n             ((symbol-function #'rg-run)\n              (lambda (pattern files dir &optional literal &rest _)\n                (setq called-pattern pattern)\n                (setq called-literal literal)\n                (setq called-files files)\n                (setq called-dir dir))))\n    (find-file \"test/data/bar.el\")\n    (let ((isearch-string \"test\"))\n      (rg-isearch-project)\n      (should (equal called-pattern \"test\"))\n      (should (eq called-literal t))\n      (should (equal called-files \"elisp\"))\n      (should (equal (expand-file-name called-dir) project-dir)))))\n\n(provide 'rg-isearch.el-test)\n\n;;; rg-isearch.el-test.el ends here\n"
  },
  {
    "path": "test/rg-menu.el-test.el",
    "content": ";;; rg-menu.el-test.el --- Tests for rg-menu.el -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/davja/\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;;; Code:\n\n\f\n;; Unit tests\n(ert-deftest rg-unit-test/enable-menu ()\n  \"Test `rg-enable-menu'.\"\n  (rg-with-temp-global-keymap\n    (rg-enable-menu)\n    (should (eq 'rg-menu (lookup-key (current-global-map) \"\\C-cs\"))))\n  (rg-with-temp-global-keymap\n   (rg-enable-menu \"\\M-s\")\n   (should (eq 'rg-menu (lookup-key (current-global-map) \"\\M-s\"))))\n\n  (let ((rg-keymap-prefix \"\\M-s\"))\n    ;; Default prefix\n    (rg-with-temp-global-keymap\n      (rg-enable-menu)\n      (should (eq 'rg-menu (lookup-key (current-global-map) \"\\M-s\"))))\n    ;; Function supplied prefix\n    (rg-with-temp-global-keymap\n      (rg-enable-menu \"\\C-ct\")\n      (should (eq 'rg-menu (lookup-key (current-global-map) \"\\C-ct\")))))\n\n  (let ((rg-mode-map (make-sparse-keymap)))\n    (rg-enable-menu)\n    (should (eq 'rg-menu (lookup-key rg-mode-map \"m\")))))\n\n(ert-deftest rg-unit/menu-transient-wrappers ()\n  \"Test the transient wrappers.\"\n  (cl-letf* ((transient-flags '(\"a\" \"b\" \"c\"))\n             (func-flags '(\"d\" \"e\"))\n             (flags-result nil)\n\n             (rg-command-line-flags-function (lambda (_) '(\"f\")))\n             ((symbol-function #'test-rerun) #'ignore)\n             ((symbol-function #'test-search)\n              (lambda ()\n                (interactive)\n                (setf flags-result (funcall rg-command-line-flags-function func-flags))))\n             ((symbol-function #'transient-args) (lambda (prefix) transient-flags))\n\n             (rg-cur-search (rg-search-create\n                 :pattern \"test\"\n                 :files \"all\"\n                 :dir \"/tmp\"\n                 :literal t\n                 :flags nil)))\n\n  (rg-menu-wrap-transient-search test-search)\n  (should (commandp #'test-search--transient))\n  (rg-menu-wrap-transient-rerun test-rerun)\n  (should (commandp #'test-rerun--transient))\n\n  (test-search--transient)\n  (should-not (seq-difference flags-result '(\"a\" \"b\" \"c\" \"d\" \"e\" \"f\")))\n\n  (test-rerun--transient)\n  (should (equal (rg-search-flags rg-cur-search) transient-flags))))\n\n(ert-deftest rg-unit/menu-rerun-custom-flags ()\n  \"Test that rerun from transient menu preserves custom flags.\"\n  (rg-define-search rg-test-search-with-flags\n    :flags '(\"--hidden\" \"--no-ignore\"))\n  (let ((captured-flags nil))\n    (cl-letf* (((symbol-function #'rg-run)\n                (lambda (pattern files dir &optional literal confirm flags)\n                  (with-current-buffer (get-buffer-create \"*rg*\")\n                    (rg-mode)\n                    (setq rg-cur-search (rg-search-create\n                                         :pattern pattern\n                                         :files files\n                                         :dir dir\n                                         :literal literal\n                                         :flags flags))\n                    (setq compilation-arguments (list \"a\" 'rg-mode 'rg-buffer-name nil)))))\n               ((symbol-function #'transient-args) (lambda (_) '(\"--multiline\" \"--hidden\"))))\n      (rg-test-search-with-flags \"test\" \"all\" \"/tmp\")\n      (with-current-buffer \"*rg*\"\n        (rg-rerun--transient)\n        (setq captured-flags (rg-search-flags rg-cur-search)))\n      ;; This is for certain from the :flags key\n      (should (member \"--no-ignore\" captured-flags))\n      ;; This is for certain from the transient-args\n      (should (member \"--multiline\" captured-flags))\n      ;; This could come from either\n      (should (member \"--hidden\" captured-flags))\n      ;; Ensure duplicates were removed\n      (should (= (length captured-flags) 3)))))\n\n(ert-deftest rg-unit/menu-transient-insert ()\n  \"Test adding new items to the menu\"\n  (transient-define-prefix rg-menu ()\n    [ \"Switches\" ]\n    [ \"Options\" ]\n    [[ \"Search\"\n       (3 \"s\" \"search\" search--transient)]\n     [ \"Rerun\"\n       (3 \"r\" \"rerun\" rerun--transient)]])\n  ;; Make sure we are not using some other rg-menu\n  (should-not (ignore-errors (transient-get-suffix 'rg-menu '(2 2))))\n  (should (transient-get-suffix 'rg-menu 'search--transient))\n  (should (transient-get-suffix 'rg-menu 'rerun--transient))\n\n  ;; Add to existing sub group\n  (rg-menu-transient-insert \"Search\" \"n\" \"new search\" 'new--transient)\n  (should (eq (plist-get\n               (cdr (transient-get-suffix 'rg-menu '(2 0 1))) :command)\n              'new--transient))\n\n  ;; Create a new sub group and add to that\n  (rg-menu-transient-insert \"Custom\" \"c\" \"custom search\" 'custom--transient)\n  (should (eq (plist-get\n               (cdr (transient-get-suffix 'rg-menu '(2 2 0))) :command)\n              'custom--transient)))\n\n(ert-deftest rg-unit/menu-define-search ()\n  \"Test adding new items to the menu\"\n  (transient-define-prefix rg-menu ()\n    [ \"Switches\" ]\n    [ \"Options\" ]\n    [[ \"Search\"\n       (3 \"s\" \"search\" search--transient)]\n     [ \"Rerun\"\n       (3 \"r\" \"rerun\" rerun--transient)]])\n  ;; Make sure we are not using some other rg-menu\n  (should-not (ignore-errors (transient-get-suffix 'rg-menu '(2 2))))\n\n  (rg-define-search menu-search\n    :menu (\"Macro\" \"m\" \"macro search\"))\n\n  (let ((subgroup (seq-elt (transient-get-suffix 'rg-menu '(2 2)) 1))\n        (entry (cdr (transient-get-suffix 'rg-menu '(2 2 0)))))\n    (should (equal (plist-get subgroup :description)\n                   \"Macro\"))\n    (should (eq (plist-get entry :command)\n                'menu-search--transient))\n    (should (equal (plist-get entry :description)\n                   \"macro search\"))\n    (should (equal (plist-get entry :key)\n                   \"m\"))))\n\n(ert-deftest rg-unit/menu-search-initial-value ()\n  \"Test extraction of flags into transient initial value.\"\n  (let ((rg-cur-search (rg-search-create\n                        :pattern \"test\"\n                        :files \"all\"\n                        :dir \"/tmp\"\n                        :literal t\n                        :flags '(\"a\" \"b\"))))\n    (with-temp-buffer\n      (should (equal (rg-menu-search-initial-value) nil))\n      (rg-mode)\n      (should-not (seq-difference\n                   (rg-menu-search-initial-value)\n                   '(\"a\" \"b\"))))))\n\n(provide 'rg-menu.el-test)\n\n;;; rg-menu.el-test.el ends here\n"
  },
  {
    "path": "test/rg.el-test.el",
    "content": ";;; rg.el-test.el --- rg.el: Tests -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2017 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;;; Code:\n\n\f\n;; Unit tests\n\n(ert-deftest rg-unit-test/case-expand-template ()\n  \"Test that `rg-apply-case-flag' handles case settings correctly.\"\n  (let (rg-initial-toggle-flags)\n    (let ((case-fold-search t))\n      (rg-apply-case-flag \"foo\")\n      (should (member  \"-i\" rg-initial-toggle-flags))\n      (rg-apply-case-flag \"fOo\")\n      (should-not (member \"-i\" rg-initial-toggle-flags)))\n    (let ((case-fold-search nil))\n      (rg-apply-case-flag \"foo\")\n      (should-not (member \"-i\" rg-initial-toggle-flags))\n      (rg-apply-case-flag \"fOo\")\n      (should-not (member \"-i\" rg-initial-toggle-flags)))\n    (let ((rg-ignore-case 'smart))\n      (rg-apply-case-flag \"foo\")\n      (should (member \"-i\" rg-initial-toggle-flags))\n      (rg-apply-case-flag \"fOo\")\n      (should-not (member \"-i\" rg-initial-toggle-flags)))\n    (let ((rg-ignore-case 'force))\n      (rg-apply-case-flag \"foo\")\n      (should (member \"-i\" rg-initial-toggle-flags))\n      (rg-apply-case-flag \"fOo\")\n      (should (member \"-i\" rg-initial-toggle-flags)))\n    (let ((rg-ignore-case nil))\n      (rg-apply-case-flag \"foo\")\n      (should-not (member \"-i\" rg-initial-toggle-flags))\n      (rg-apply-case-flag \"fOo\")\n      (should-not (member \"-i\" rg-initial-toggle-flags)))))\n\n(ert-deftest rg-unit-test/custom-command-line-flags ()\n  \"Test that `rg-command-line-flags' is added to the template.\"\n  (let ((rg-executable \"rg\")\n        (rg-custom-type-aliases nil)\n        (rg-command-line-flags '(\"--foo\" \"--bar\")))\n    (should (s-matches? (rg-regexp-anywhere-but-last \"--foo --bar\")\n                        (rg-build-command \"\" \"\" nil nil)))))\n\n(ert-deftest rg-unit-test/custom-command-line-function ()\n  \"Test that when `rg-command-line-flags' is a function, the returned\n  list of flags are added to the template.\"\n  (let ((rg-command \"rg\")\n        (rg-custom-type-aliases nil)\n        (rg-command-line-flags (lambda () '(\"--foo\" \"--bar\"))))\n    (should (s-matches? (rg-regexp-anywhere-but-last \"--foo --bar\")\n                        (rg-build-command \"\" \"\" nil nil)))))\n\n(ert-deftest rg-unit-test/rg-buffer-name-string ()\n  \"Test that function `rg-buffer-name' will return correct buffer\nname if variable `rg-buffer-name' is string.\"\n  (let ((rg-buffer-name \"rg results\"))\n    (should (string= \"*rg results*\" (rg-buffer-name)))))\n\n(ert-deftest rg-unit-test/rg-buffer-name-function ()\n  \"Test that function `rg-buffer-name' will return correct buffer\nname if variable `rg-buffer-name' is function.\"\n  (let ((rg-buffer-name (lambda () \"\" \"rg results\")))\n    (should (string= \"*rg results*\" (rg-buffer-name)))))\n\n(ert-deftest rg-unit-test/rg-buffer-name-dirlocals ()\n  \"Test that `rg-buffer-name' is set from dir-locals.el.\"\n  ;; This test covers two cases:\n  ;; - that dir-locals from search dir is applied at all\n  ;; - that dir-locals from search dir is applied if search is\n  ;;   started from file buffers\n  :tags '(need-rg)\n  (let ((safe-local-variable-values '((rg-buffer-name . \"from dir locals\"))))\n    (find-file (concat default-directory \"test/data/foo.baz\"))\n    (rg-run \"foo\" \"*.baz\" (concat default-directory \"dirlocals\"))\n    (should (get-buffer \"*from dir locals*\"))))\n\n(ert-deftest rg-unit-test/save-search-as-name ()\n  \"Verify exit messages.\"\n  :tags '(need-rg)\n  (let ((rg-buffer-name \"rg results\"))\n    (rg-run \"foo\" \"*.baz\" (concat default-directory \"test/data\"))\n    (with-current-buffer (rg-buffer-name)\n      (rg-save-search-as-name \"bar\")\n      (should (string= \"*rg results bar*\" (buffer-name))))))\n\n(ert-deftest rg-unit-test/toggle-command-flag ()\n  \"Test `rg-list-toggle'.\"\n  (let ((testflag \"--foo\")\n        flaglist)\n    (setq flaglist (rg-list-toggle testflag flaglist))\n    (should (member testflag flaglist))\n    (setq flaglist (rg-list-toggle testflag flaglist))\n    (should-not (member testflag flaglist))))\n\n(ert-deftest rg-unit-test/rerun-change-regexp-literal ()\n  \"Test result of `rg-rerun-change-regexp' and `rg-rerun-change-literal'.\"\n  (let ((rg-cur-search (rg-search-create :pattern \"pattern\" :files \"elisp\" :dir \"/tmp/test\")))\n    (cl-letf (((symbol-function #'rg-rerun) #'ignore)\n              ((symbol-function #'rg-read-pattern) (lambda (&rest _) \"new-pattern\")))\n      (rg-rerun-change-regexp)\n      (should (equal\n               (rg-search-create :pattern \"new-pattern\"\n                                 :files \"elisp\"\n                                 :dir \"/tmp/test\"\n                                 :literal nil)\n               rg-cur-search))\n      (rg-rerun-change-literal)\n      (should (equal\n               (rg-search-create :pattern \"new-pattern\"\n                                 :files \"elisp\"\n                                 :dir \"/tmp/test\"\n                                 :literal t)\n               rg-cur-search))\n      (rg-rerun-change-regexp)\n      (should (eq (rg-search-literal rg-cur-search) nil)))))\n\n(ert-deftest rg-unit-test/read-pattern-correct-read-func ()\n  \"Test that `rg-read-pattern' choose the correct read function depending\non emacs version.\"\n  (let (called prompt-result)\n    (cl-letf (((symbol-function #'read-string) (lambda (pr default &rest _)\n                                                 (setq called 'read-string)\n                                                 (setq prompt-result pr)))\n              ((symbol-function #'read-regexp) (lambda (pr &rest _)\n                                                 (setq called 'read-regexp)\n                                                 (setq prompt-result pr))))\n      (rg-read-pattern nil \"foo\")\n      (should (eq called 'read-regexp))\n      (should (equal prompt-result \"Regexp search for\")))))\n\n(ert-deftest rg-unit-test/rerun-change-files ()\n  \"Test result of `rg-rerun-change-files'.\"\n  (let ((rg-cur-search (rg-search-new \"regexp\" \"elisp\" \"/tmp/test\")))\n    (cl-letf (((symbol-function #'rg-rerun) #'ignore)\n              ((symbol-function #'completing-read) (lambda (&rest _) \"cpp\")))\n      (rg-rerun-change-files)\n      (should (equal (rg-search-new \"regexp\" \"cpp\" \"/tmp/test\") rg-cur-search)))))\n\n(ert-deftest rg-unit-test/rerun-change-dir ()\n  \"Test result of `rg-rerun-change-dir'.\"\n  (let ((rg-cur-search (rg-search-new \"regexp\" \"elisp\" \"/tmp/test\")))\n    (cl-letf (((symbol-function #'rg-rerun) #'ignore)\n              ((symbol-function #'read-directory-name) (lambda (&rest _) \"/tmp/new\")))\n      (rg-rerun-change-dir)\n      (should (equal (rg-search-new \"regexp\" \"elisp\" \"/tmp/new\") rg-cur-search)))))\n\n(ert-deftest rg-unit-test/custom-toggle ()\n  \"Test `rg-define-toggle' macro.\"\n  (let ((rg-cur-search (rg-search-create :pattern \"regexp\" :files \"elisp\" :dir \"/tmp/test\")))\n    (cl-letf (((symbol-function #'rg-rerun) #'ignore))\n      (rg-define-toggle \"--foo\")\n      (should (functionp 'rg-custom-toggle-flag-foo))\n      (should-not (member \"--foo\" rg-initial-toggle-flags))\n      (rg-define-toggle \"--bar\" nil t)\n      (should (functionp 'rg-custom-toggle-flag-bar))\n      (should (member \"--bar\" rg-initial-toggle-flags))\n\n      (simulate-rg-run (rg-search-pattern rg-cur-search)\n                       (rg-search-files rg-cur-search)\n                       (rg-search-dir rg-cur-search))\n\n      (rg-custom-toggle-flag-foo)\n      (should (member \"--foo\" (rg-search-flags rg-cur-search)))\n      (should (member \"--bar\" (rg-search-flags rg-cur-search)))\n\n      (rg-custom-toggle-flag-foo)\n      (should-not (member \"--foo\" (rg-search-flags rg-cur-search)))\n      (should (member \"--bar\" (rg-search-flags rg-cur-search)))\n      (rg-custom-toggle-flag-bar)\n      (should-not (member \"--foo\" (rg-search-flags rg-cur-search)))\n      (should-not (member \"--bar\" (rg-search-flags rg-cur-search)))\n\n      (rg-custom-toggle-flag-bar)\n      (should-not (member \"--foo\" rg-initial-toggle-flags))\n      (should (member \"--bar\" rg-initial-toggle-flags)))))\n\n(ert-deftest rg-unit-test/custom-toggle-key-binding ()\n  \"Test `rg-define-toggle' macro key bindings.\"\n  (let ((rg-cur-search (rg-search-create :pattern \"regexp\" :files \"elisp\" :dir \"/tmp/test\")))\n    (cl-letf (((symbol-function #'recompile) #'ignore))\n      (rg-define-toggle \"--baz\" \"b\")\n      (should (functionp 'rg-custom-toggle-flag-baz))\n      (should (eq 'rg-custom-toggle-flag-baz (lookup-key rg-mode-map \"b\"))))))\n\n(ert-deftest rg-unit-test/custom-toggle-double-definition ()\n  \"Test multiple clashing definitions of same flag and bindings in\n`rg-define-toggle' macro.\"\n  (let ((rg-cur-search (rg-search-create :pattern \"regexp\" :files \"elisp\" :dir \"/tmp/test\")))\n    (cl-letf (((symbol-function #'recompile) #'ignore))\n      (rg-define-toggle \"--qux\" nil t)\n      (should (functionp 'rg-custom-toggle-flag-qux))\n      (should-not (eq 'rg-custom-toggle-flag-qux (lookup-key rg-mode-map \"q\")))\n      (should (member \"--qux\" rg-initial-toggle-flags))\n      (rg-define-toggle \"--qux\" \"q\")\n      (should (functionp 'rg-custom-toggle-flag-qux))\n      (should (eq 'rg-custom-toggle-flag-qux (lookup-key rg-mode-map \"q\")))\n      (should-not (member \"--qux\" rg-initial-toggle-flags))\n      (rg-define-toggle \"--qux\" \"z\")\n      (should (functionp 'rg-custom-toggle-flag-qux))\n      (should (eq 'rg-custom-toggle-flag-qux (lookup-key rg-mode-map \"z\")))\n      (rg-define-toggle \"--quux\" \"q\")\n      (should (eq 'rg-custom-toggle-flag-quux (lookup-key rg-mode-map \"q\")))\n      (should-not (eq 'rg-custom-toggle-flag-qux (lookup-key rg-mode-map \"q\"))))))\n\n(ert-deftest rg-unit-test/build-command-files ()\n  \"Test that`rg-build-command' convert files argument to correct type\nalias.\"\n  (let ((rg-executable \"rg\")\n        (rg-custom-type-aliases nil)\n        full-command)\n    (setq full-command (rg-build-command \"foo\" \"cpp\" nil nil))\n    (should (s-matches? \"rg.*? +--type=cpp.*? +foo\" full-command))\n    (setq full-command (rg-build-command \"foo\" \"everything\" nil nil))\n    (should-not (s-matches? \"rg.*? +--type=.*? +foo\" full-command))\n    (setq full-command (rg-build-command \"foo\" \"bar\" nil nil))\n    (should (s-matches? (concat \"rg.*? +--type-add=\"\n                                (regexp-quote (shell-quote-argument \"custom:bar\"))\n                                \" +--type=\\\"?custom.*? +foo\")\n                        full-command))))\n\n(ert-deftest rg-unit-test/build-command-type ()\n  \"Test `rg-build-template' template creation.\"\n  (let* ((rg-executable \"rg\")\n         (rg-custom-type-aliases nil)\n         (notype-command (rg-build-command \"query\" \"everything\" nil nil))\n         (builtin-type-command (rg-build-command \"query\" \"elisp\" nil nil))\n         (custom-type-command (rg-build-command \"query\" \"glob\" nil nil))\n         (type-pattern (rg-regexp-anywhere-but-last \"--type=[^ ]+\"))\n         (type-add-pattern (rg-regexp-anywhere-but-last\n                            (concat\n                             \"--type-add=\"\n                             (s-replace \"----\" \"[^ ]+\"\n                                        (regexp-quote\n                                         (shell-quote-argument \"custom:----\")))))))\n    (should (s-matches? (rg-regexp-anywhere \"-e query\") notype-command))\n    (should-not (s-matches? type-pattern notype-command))\n    (should-not (s-matches? type-add-pattern notype-command))\n    (should (s-matches? type-pattern builtin-type-command))\n    (should-not (s-matches? type-add-pattern builtin-type-command))\n    (should (s-matches? type-add-pattern custom-type-command))\n    (should (s-matches? (rg-regexp-anywhere-but-last \"--type=custom\") custom-type-command))))\n\n(ert-deftest rg-unit-test/build-command-explicit-dir ()\n  \"Test that `rg-build-command' use explicit current dir on some platforms.\"\n  (let ((rg-executable \"rg\"))\n    (should-not (string-match \"\\\\.$\" (rg-build-command \"query\" \"glob\" nil nil)))\n    (let ((system-type 'darwin))\n      (should (string-match \"\\\\.$\" (rg-build-command \"query\" \"glob\" nil nil))))\n    ;; Need w32-shell-dos-semantics when faking system-type on Linux\n    (cl-letf (((symbol-function (intern \"w32-shell-dos-semantics\")) (lambda ()))\n              (system-type 'windows-nt))\n      (should (string-match \"\\\\.$\" (rg-build-command \"query\" \"glob\" nil nil))))))\n\n(ert-deftest rg-unit-test/default-alias ()\n  \"Test that `rg-default-alias' detects the current file and selects\nmatching alias.\"\n  (find-file \"test/data/foo.el\")\n  (should (equal (car (rg-default-alias)) \"elisp\"))\n  (find-file \"test/data/foo.baz\")\n  (should (equal (car (rg-default-alias)) rg-default-alias-fallback))\n  (let ((rg-custom-type-aliases '((\"test\" . \"*.baz\"))))\n    (find-file \"test/data/foo.baz\")\n    (should (equal (car (rg-default-alias)) \"test\"))))\n\n(ert-deftest rg-unit-test/navigate-file-message ()\n  \"Test that `rg-navigate-file-message' find font-lock-face matches correctly.\"\n  (let (pos limit)\n    (with-temp-buffer\n      (insert\n       \"noproperty\"\n       (propertize \"match1\" 'rg-file-message t)\n       (propertize \"someotherproperty\" 'rg-file-message nil)\n       \"noproperty2\"\n       (propertize \"othermatch\" 'rg-file-message t))\n      (setq pos (rg-navigate-file-message (point-min) (point-max) 1))\n      (goto-char pos)\n      (should (looking-at \"match1\"))\n      (setq pos (rg-navigate-file-message pos (point-max) 1))\n      (goto-char pos)\n      (should (looking-at \"othermatch\"))\n      (setq pos (rg-navigate-file-message pos (point-min) -1))\n      (goto-char pos)\n      (should (looking-at \"match1\"))\n      (setq pos (rg-navigate-file-message pos (point-max) 1))\n      (goto-char pos)\n      (should (looking-at \"othermatch\"))\n      (setq limit (+ pos 4))\n      (setq pos (rg-navigate-file-message pos limit 1))\n      (should (eq pos limit)))))\n\n(ert-deftest rg-unit/next-prev-file ()\n  \"Test that `rg-next-file' and `rg-prev-file' dispatch calls as it should.\"\n  (let (called arg)\n    (cl-letf (((symbol-function #'rg-navigate-file-group)\n               (lambda (n)\n                 (setq called 'rg-navigate-file-group\n                       arg n)))\n              ((symbol-function #'compilation-next-file)\n               (lambda (n)\n                 (setq called 'compilation-next-file\n                       arg n)))\n              ((symbol-function #'compilation-previous-file)\n               (lambda (n)\n                 (setq called 'compilation-previous-file\n                       arg n))))\n      (let ((rg-group-result t))\n        (rg-next-file 1)\n        (should (eq called 'rg-navigate-file-group))\n        (should (eq arg 1))\n        (rg-prev-file 1)\n        (should (eq called 'rg-navigate-file-group))\n        (should (eq arg (- 1))))\n      (let ((rg-group-result nil))\n        (rg-next-file 1)\n        (should (eq called 'compilation-next-file))\n        (should (eq arg 1))\n        (rg-prev-file 1)\n        (should (eq called 'compilation-previous-file))\n        (should (eq arg 1))))))\n\n(ert-deftest rg-unit/match-grouped-filename ()\n  \"Test that `rg-match-grouped-filename' finds correct match and restores state.\"\n  (let (saved-pos)\n    (with-temp-buffer\n      (insert\n       \"some random text\\n\"\n       \"File: matched/text/file.foo\\n\"\n       \"4:1:   Some matched text\")\n      (goto-char (point-min))\n      (re-search-forward \"Some match\")\n      (setq saved-pos (point))\n      (should (equal \"matched/text/file.foo\" (car (rg-match-grouped-filename))))\n      (should (equal \"Some match\" (match-string 0)))\n      (should (eq saved-pos (point))))))\n\n(ert-deftest rg-unit-test/global-keymap ()\n  \"Test global keymap.\"\n  (let ((rg-use-transient-menu nil))\n    ;; Default prefix\n    (rg-with-temp-global-keymap\n     (rg-enable-default-bindings)\n     (should (eq rg-global-map (lookup-key (current-global-map) \"\\C-cs\"))))\n    ;; Function supplied prefix\n    (rg-with-temp-global-keymap\n     (rg-enable-default-bindings \"\\M-s\")\n     (should (eq rg-global-map (lookup-key (current-global-map) \"\\M-s\"))))\n    ;; Customized prefix\n    (let ((rg-keymap-prefix \"\\M-s\"))\n      ;; Default prefix\n      (rg-with-temp-global-keymap\n       (rg-enable-default-bindings)\n       (should (eq rg-global-map (lookup-key (current-global-map) \"\\M-s\"))))\n      ;; Function supplied prefix\n      (rg-with-temp-global-keymap\n       (rg-enable-default-bindings \"\\C-ct\")\n       (should (eq rg-global-map (lookup-key (current-global-map) \"\\C-ct\")))))\n    ;; Make sure rg-global-map comes into play\n    (rg-with-temp-global-keymap\n     (rg-enable-default-bindings)\n     (should (eq 'rg (lookup-key (current-global-map) \"\\C-csr\")))\n     ;; Modify global map\n     (define-key rg-global-map \"0\" 'foo)\n     (should (eq 'foo (lookup-key (current-global-map) \"\\C-cs0\"))))))\n\n(ert-deftest rg-unit/literal-search ()\n  \"Test `rg-literal'.\"\n  (cl-letf* ((called-literal nil)\n             ((symbol-function #'rg-run)\n              (lambda (_pattern _files _dir &optional literal &rest _)\n                (setf called-literal literal))))\n    (rg-literal \"foo\" \"elisp\" \"/tmp/test\")\n    (should-not (eq called-literal nil))))\n\n(ert-deftest rg-unit/regexp-search ()\n  \"Test `rg'.\"\n  (cl-letf* ((called-literal nil)\n             ((symbol-function #'rg-run)\n              (lambda (_pattern _files _dir &optional literal &rest _)\n                (setq called-literal literal))))\n    (rg \"foo\" \"elisp\" \"/tmp/test\")\n    (should (eq called-literal nil))))\n\n(ert-deftest rg-unit/set-search-defaults ()\n  \"Test rg-define-search helper defun rg-set-search-defaults.\"\n  (let  ((defaults (rg-set-search-defaults nil)))\n    (should (eq (plist-get defaults :confirm) 'never))\n    (should (eq (plist-get defaults :format) 'regexp))\n    (should (eq (plist-get defaults :query) 'ask))\n    (should (eq (plist-get defaults :files) 'ask))\n    (should (eq (plist-get defaults :dir) 'ask))))\n\n(ert-deftest rg-unit/search-parse-local-bindings-confirm ()\n  \"Test rg-define-search helper defun rg-search-parse-local-bindings.\nTest `:confirm' directive.\"\n  (let  ((prefix (rg-search-parse-local-bindings '(:confirm prefix)))\n         (never (rg-search-parse-local-bindings '(:confirm never)))\n         (always (rg-search-parse-local-bindings '(:confirm always))))\n    (should (null (cadr (assq 'confirm never))))\n    (should (cadr (assq 'confirm always)))\n    (should (eq (cadr (cadr (assq 'confirm prefix))) 'current-prefix-arg))))\n\n(ert-deftest rg-unit/search-parse-local-bindings-query ()\n  \"Test rg-define-search helper defun rg-search-parse-local-bindings.\nTest `:query' directive.\"\n  (let  ((ask (rg-search-parse-local-bindings '(:query ask)))\n         (form (rg-search-parse-local-bindings '(:query (form))))\n         (point (rg-search-parse-local-bindings '(:query point))))\n    (should (null (assq 'query ask)))\n    (should (equal (cadr (assq 'query form)) '(form)))\n    (should (equal (cadr (assq 'query point)) '(or (rg-tag-default)\n                                                   (rg-read-pattern literal))))))\n\n(ert-deftest rg-unit/search-parse-local-bindings-dir ()\n  \"Test rg-define-search helper defun rg-search-parse-local-bindings.\nTest `:dir' directive.\"\n  (let  ((ask (rg-search-parse-local-bindings '(:dir ask)))\n         (project (rg-search-parse-local-bindings '(:dir project)))\n         (current (rg-search-parse-local-bindings '(:dir current)))\n         (form (rg-search-parse-local-bindings '(:dir (form)))))\n    (should (null (assq 'dir ask)))\n    (should (equal (cadr (assq 'dir project)) '(rg-project-root buffer-file-name)))\n    (should (equal (cadr (assq 'dir current)) 'default-directory))\n    (should (equal (cadr (assq 'dir form)) '(form)))))\n\n(ert-deftest rg-unit/search-parse-local-bindings-files ()\n  \"Test rg-define-search helper defun rg-search-parse-local-bindings.\nTest `:files' directive.\"\n  (let  ((ask (rg-search-parse-local-bindings '(:files ask)))\n         (current (rg-search-parse-local-bindings '(:files current)))\n         (form (rg-search-parse-local-bindings '(:files (form)))))\n    (should (null (assq 'files ask)))\n    (should (equal (cadr (assq 'files current)) '(car (rg-default-alias))))\n    (should (equal (cadr (assq 'files form)) '(form)))))\n\n(ert-deftest rg-unit/search-parse-local-bindings-flags ()\n  \"Test rg-define-search helper defun rg-search-parse-global-bindings.\nTest `:flags' directive.\"\n  (let  ((ask (rg-search-parse-local-bindings '(:flags ask)))\n         (form (rg-search-parse-local-bindings '(:flags '(\"--flag\")))))\n    (should (cadr (assq 'flags ask)))\n    (should (equal (cadr (assq 'flags form))\n                   (quote (funcall rg-command-line-flags-function '(\"--flag\")))))))\n\n(ert-deftest rg-unit/search-parse-interactive-args ()\n  \"Test rg-define-search helper defun rg-search-parse-interactive-args.\"\n  (let  ((empty (rg-search-parse-interactive-args nil))\n         (query (rg-search-parse-interactive-args '(:query ask)))\n         (files (rg-search-parse-interactive-args '(:files ask)))\n         (dir (rg-search-parse-interactive-args '(:dir ask)))\n         (flags (rg-search-parse-interactive-args '(:flags ask))))\n    (should (null empty))\n    (should (equal (cadr (assq 'query query)) 'rg-read-pattern))\n    (should (equal (cadr (assq 'files files)) 'rg-read-files ))\n    (should (equal (cadr (assq 'dir dir)) 'read-directory-name))\n    (should (equal (caar (cddr (assq 'flags flags))) 'read-string))))\n\n(ert-deftest rg-unit/builtin-aliases-empty-strings ()\n  \"Test that empty strings in builtin aliases are filtered out.\"\n  (cl-letf (((symbol-function #'rg-invoke-rg-type-list)\n             (lambda () \"\\n\\n foo: *.foo,*.fo\\n\\n bar: *.bar,*.ba\\n\")))\n    (equal (rg-list-builtin-type-aliases)\n           '((\"foo\" . \"*.foo *.fo\") (\"bar\" . \"*.bar *.ba\")))))\n\n(ert-deftest rg-unit/prepend-space ()\n  \"Test rg-prepend-space.\"\n  (should (equal (rg-prepend-space \"foo\" (length \"foo\")) \"foo\"))\n  (should (equal (rg-prepend-space \"foo\" (1+ (length \"foo\"))) \" foo\"))\n  (should (equal (rg-prepend-space \"foo\" (1- (length \"foo\"))) \"foo\")))\n\n\f\n;; Integration tests\n\n(ert-deftest rg-integration-test/search-alias-builtin ()\n  \"Test that rg builtin aliases works.\"\n  :tags '(need-rg)\n  (let ((rg-group-result nil)\n        (rg-ignore-case 'force))\n    (rg-run \"hello\" \"elisp\" (concat default-directory \"test/data\"))\n    (rg-with-current-result\n      (let ((bufstr (buffer-substring-no-properties (point-min) (point-max))))\n        (should (= 3 (s-count-matches \"foo.el.*hello\" bufstr)))\n        (should (= 3 (s-count-matches \"bar.el.*hello\" bufstr)))\n        (should (= 0 (s-count-matches \"foo.baz.*hello\" bufstr)))\n        (should (= 0 (s-count-matches \"bar.baz.*hello\" bufstr)))))))\n\n(ert-deftest rg-integration-test/search-alias-custom ()\n  \"Test that aliases defined in `rg-custom-type-aliases' work if explicitly selected.\"\n  :tags '(need-rg)\n  (let ((rg-group-result nil)\n        (rg-ignore-case 'force)\n        (rg-custom-type-aliases '((\"test\" . \"*.baz\"))))\n    (rg-run \"hello\" \"test\" (concat default-directory \"test/data\"))\n    (rg-with-current-result\n      (let ((bufstr (buffer-substring-no-properties (point-min) (point-max))))\n        (should (= 0 (s-count-matches \"foo.el.*hello\" bufstr)))\n        (should (= 0 (s-count-matches \"bar.el.*hello\" bufstr)))\n        (should (= 3 (s-count-matches \"foo.baz.*hello\" bufstr)))\n        (should (= 3 (s-count-matches \"bar.baz.*hello\" bufstr)))))))\n\n(ert-deftest rg-integration-test/search-alias-all-custom ()\n  \"Test that aliases defined in `rg-custom-type-ailiases' work if\n  implicitly selected via '--type=all'.\"\n  :tags '(need-rg)\n  (let ((rg-group-result nil)\n        (rg-ignore-case 'force)\n        (rg-custom-type-aliases '((\"test\" . \"*.baz\"))))\n    (rg-run \"hello\" \"all\" (concat default-directory \"test/data\"))\n    (rg-with-current-result\n      (let ((bufstr (buffer-substring-no-properties (point-min) (point-max))))\n        (should (= 3 (s-count-matches \"foo.el.*hello\" bufstr)))\n        (should (= 3 (s-count-matches \"bar.el.*hello\" bufstr)))\n        (should (= 3 (s-count-matches \"foo.baz.*hello\" bufstr)))\n        (should (= 3 (s-count-matches \"bar.baz.*hello\" bufstr)))))))\n\n(ert-deftest rg-integration-test/search-alias-custom-lambda ()\n  \"Test that aliases defined via lambdas in `rg-custom-type-aliases' work.\"\n  :tags '(need-rg)\n  (let ((rg-group-result nil)\n        (rg-ignore-case 'force)\n        (rg-custom-type-aliases '((lambda () '(\"test\" . \"*.baz\")))))\n    (rg-run \"hello\" \"test\" (concat default-directory \"test/data\"))\n    (rg-with-current-result\n      (let ((bufstr (buffer-substring-no-properties (point-min) (point-max))))\n        (should (= 0 (s-count-matches \"foo.el.*hello\" bufstr)))\n        (should (= 0 (s-count-matches \"bar.el.*hello\" bufstr)))\n        (should (= 3 (s-count-matches \"foo.baz.*hello\" bufstr)))\n        (should (= 3 (s-count-matches \"bar.baz.*hello\" bufstr)))))))\n\n(ert-deftest rg-integration-test/search-no-alias()\n  \"Test that custom file pattern that is not an alias works.\"\n  :tags '(need-rg)\n  (let ((rg-group-result nil)\n        (rg-ignore-case 'force))\n    (rg-run \"hello\" \"*.baz\" (concat default-directory \"test/data\"))\n    (rg-with-current-result\n      (let ((bufstr (buffer-substring-no-properties (point-min) (point-max))))\n        (should (= 0 (s-count-matches \"foo.el.*hello\" bufstr)))\n        (should (= 0 (s-count-matches \"bar.el.*hello\" bufstr)))\n        (should (= 3 (s-count-matches \"foo.baz.*hello\" bufstr)))\n        (should (= 3 (s-count-matches \"bar.baz.*hello\" bufstr)))))))\n\n(ert-deftest rg-integration-test/rg-get-type-aliases()\n  \"Test that rg-get-type-aliases combines the aliases and priorities correctly.\"\n  :tags '(need-rg)\n  (let* ((rg-custom-type-aliases '())\n        (builtin (rg-list-builtin-type-aliases)))\n    ;; No custom type aliases and no prioritized aliases gives the\n    ;; ripgrep internal aliases.\n    (should (rg-set-equal-p (rg-get-type-aliases 'skip-internal) builtin))\n    (setq rg-builtin-type-aliases-cache nil)\n    (let* ((rg-prioritized-type-aliases '(\"cpp\" \"puppet\" \"elisp\"))\n           (result (rg-get-type-aliases 'skip-internal)))\n      ;; Using prioritized aliases doesn't modify the set of aliases\n      (should (rg-set-equal-p result builtin))\n      ;; The three first aliases should be the prioritized ones.\n      (should (equal (mapcar #'car (seq-take result 3)) rg-prioritized-type-aliases))\n      (setq rg-builtin-type-aliases-cache nil)\n      (let* ((rg-custom-type-aliases '((\"foo\" . \"*.foo\") (\"bar\" . \"*.bar\")))\n             (result (rg-get-type-aliases 'skip-internal)))\n        ;; Custom aliases are included.\n        (should (rg-set-equal-p result (append rg-custom-type-aliases builtin)))\n        ;; The two first are the custom aliases\n        (should (rg-set-equal-p (mapcar #'car (seq-take result 2)) (mapcar #'car (seq-take rg-custom-type-aliases 2))))\n        ;; The three following are the prioritized aliases.\n        (should (rg-set-equal-p (mapcar #'car (seq-take (seq-drop result 2) 3)) rg-prioritized-type-aliases))))))\n\n(ert-deftest rg-integration-test/rg-order-of-prioritized-type-aliases()\n  \"Test that rg-get-type-aliases honors the order of the `rg-prioritized-type-aliases' var.\"\n  :tags '(need-rg)\n  (let* ((rg-custom-type-aliases '())\n         (rg-prioritized-type-aliases '(\"cpp\" \"puppet\" \"elisp\"))\n         (builtin (rg-list-builtin-type-aliases))\n         (result (rg-get-type-aliases 'skip-internal)))\n    (should (equal (mapcar #'car (seq-take result 3)) rg-prioritized-type-aliases))\n    (setq rg-prioritized-type-aliases '(\"puppet\" \"cpp\" \"elisp\"))\n    (setq result (rg-get-type-aliases 'skip-internal))\n    (should (equal (mapcar #'car (seq-take result 3)) rg-prioritized-type-aliases))))\n\n(ert-deftest rg-integration-test/search-history ()\n  \"Test that `rg-history' gets updated.\"\n  :tags '(need-rg)\n  (let ((rg-history nil))\n    (rg-run \"hello\" \"all\" \"/tmp/test\")\n    (rg-with-current-result\n      (should (member (car compilation-arguments) rg-history)))))\n\n(ert-deftest rg-integration-test/search-uppercase-regexp ()\n  \"Test that uppercase search triggers case sensitive search.\"\n  :tags '(need-rg)\n  (let ((rg-group-result nil)\n        (rg-ignore-case 'smart))\n    (rg-run \"Hello\" \"all\" (concat default-directory \"test/data\"))\n    (rg-with-current-result\n      (let ((bufstr (buffer-substring-no-properties (point-min) (point-max))))\n        (should (= 1 (s-count-matches \"foo.el.*hello\" bufstr)))\n        (should (= 1 (s-count-matches \"bar.el.*hello\" bufstr)))))))\n\n(ert-deftest rg-integration-test/search-case-sensitive-regexp ()\n  \"Test explicit case sensitive search.\"\n  :tags '(need-rg)\n  (let ((rg-group-result nil)\n        (rg-ignore-case 'nil))\n    (rg-run \"hello\" \"all\" (concat default-directory \"test/data\")))\n  (rg-with-current-result\n    (let ((bufstr (buffer-substring-no-properties (point-min) (point-max))))\n      (should (= 1 (s-count-matches \"foo.el.*hello\" bufstr)))\n      (should (= 1 (s-count-matches \"bar.el.*hello\" bufstr))))))\n\n(ert-deftest rg-integration-test/project-root ()\n  \"Test that all paths in `rt-project-root' gives valid results.\nThis test abuse the internal priority of `rg-project-root', by first\nchecking the root and then successively disable the internally used\nmethod. \"\n  (rg-check-git-project-root)\n  (with-eval-after-load 'projectile\n    (fmakunbound 'projectile-project-root))\n\n  ;; ffip\n  (rg-check-git-project-root)\n  (with-eval-after-load 'find-file-in-project\n    (fmakunbound 'ffip-project-root))\n\n  ;; project.el\n  (rg-check-git-project-root)\n  (with-eval-after-load 'project\n    (fmakunbound 'project-current))\n\n  ;; vc-backend\n  (rg-check-git-project-root)\n  ;; default\n  (should (equal (expand-file-name\n                  (rg-project-root \"/tmp/foo.el\"))\n                 \"/tmp/\")))\n\n(ert-deftest rg-integration-test/imenu-populated ()\n  \"Test that the imenu entries are correct.\"\n  :tags '(need-rg)\n  (rg-run \"imenu\" \"elisp\" (concat default-directory \"test/data\"))\n  (with-current-buffer (rg-buffer-name)\n    (rg-wait-for-search-result)\n    (let ((ientries (funcall imenu-create-index-function)))\n      (should (equal (length ientries) 1))\n      (should (equal\n               '(\"limenu.el\")\n               (mapcar #'car ientries)))))\n  (rg-run \"hello\" \"*.baz\" (concat default-directory \"test/data\"))\n  (with-current-buffer (rg-buffer-name)\n    (rg-wait-for-search-result)\n    (let ((ientries (funcall imenu-create-index-function)))\n      (should (equal (length ientries) 2))\n      (should (equal\n               '(\"bar.baz\" \"foo.baz\")\n               (seq-sort #'string-lessp (mapcar #'car ientries)))))))\n\n(ert-deftest rg-integration/command-hiding-hide ()\n  \"Test command hiding when `rg-hide-command` is non nil.\"\n  :tags '(need-rg)\n  (rg-test-with-command-start \"hello\"\n     (should (get-text-property (point) 'display))\n     (rg-toggle-command-hiding)\n     (should-not (get-text-property (point) 'display))))\n\n(ert-deftest rg-integration/command-hiding-nohide ()\n  \"Test command hiding when `rg-hide-command` is nil.\"\n  :tags '(need-rg)\n  (let ((rg-hide-command nil))\n    (rg-test-with-command-start \"hello\"\n        (should-not (get-text-property (point) 'display))\n        (rg-toggle-command-hiding)\n        (should (get-text-property (point) 'display)))))\n\n(ert-deftest rg-integration/nogroup-show-columns ()\n  \"Test that column numbers are shown in no group mode if enabled.\"\n  :tags '(need-rg)\n  (let ((rg-group-result nil)\n        (rg-show-columns t))\n    (rg-test-with-first-error \"hello\"\n     (should (looking-at \".*:[0-9]:[0-9]\")))))\n\n(ert-deftest rg-integration/nogroup-hide-columns ()\n  \"Test that column numbers are hidden in no group mode if disabled.\"\n  :tags '(need-rg)\n  (let ((rg-group-result nil)\n        (rg-show-columns nil))\n    (rg-test-with-first-error \"hello\"\n     (should (looking-at \".*:[0-9]:[^0-9]\")))))\n\n(ert-deftest rg-integration/positions-line-only ()\n  \"Test line position format without alignment.\"\n  :tags '(need-rg)\n  (let ((rg-align-position-numbers nil))\n    (rg-test-with-first-error \"hello\"\n     (should (looking-at \"[0-9]:\")))))\n\n(ert-deftest rg-integration/positions-line-column ()\n  \"Test line and column position format without alignment.\"\n  :tags '(need-rg)\n  (let ((rg-align-position-numbers nil)\n        (rg-show-columns t))\n    (rg-test-with-first-error \"hello\"\n     (should (looking-at \"[0-9]+:[0-9]+:\")))))\n\n(ert-deftest rg-integration/positions-align-line ()\n  \"Test line position format with alignment.\"\n  :tags '(need-rg)\n  (let ((rg-align-position-numbers t))\n    (rg-test-with-first-error \"hello\"\n     (should (looking-at (format\n                          \" \\\\{0,3\\\\}[0-9]\\\\{1,4\\\\}%s\"\n                          rg-align-position-content-separator)))\n     (should (equal (length (match-string 0))\n                    (1+ rg-align-line-number-field-length))))\n    (let ((rg-align-position-content-separator \"#\"))\n      (rg-test-with-first-error \"hello\"\n       (should (looking-at (format \" \\\\{0,4\\\\}[0-9]\\\\{1,5\\\\}%s\"\n                                   rg-align-position-content-separator)))))))\n\n(ert-deftest rg-integration/positions-align-line-column ()\n  \"Test line and column position format with alignment.\"\n  :tags '(need-rg)\n  (let ((rg-show-columns t)\n        (rg-align-position-numbers t))\n    (rg-test-with-first-error \"hello\"\n     (should (looking-at (format \" \\\\{0,3\\\\}[0-9]\\\\{1,4\\\\}%s \\\\{0,2\\\\}[0-9]\\\\{1,3\\\\}%s\"\n                                 rg-align-line-column-separator\n                                 rg-align-position-content-separator)))\n     (should (equal (length (match-string 0))\n                    (+ rg-align-line-number-field-length\n                       rg-align-column-number-field-length\n                       2))))\n    (let ((rg-align-position-content-separator \";\")\n          (rg-align-line-column-separator \"&\"))\n      (rg-test-with-first-error \"hello\"\n       (should (looking-at (format \" \\\\{0,3\\\\}[0-9]\\\\{1,4\\\\}%s \\\\{0,2\\\\}[0-9]\\\\{1,3\\\\}%s\"\n                                   rg-align-line-column-separator\n                                   rg-align-position-content-separator)))\n       (should (equal (length (match-string 0))\n                      (+ rg-align-line-number-field-length\n                         rg-align-column-number-field-length\n                         2)))))))\n\n(ert-deftest rg-integration/positions-align-context-line ()\n  \"Test line position format with alignment.\"\n  :tags '(need-rg)\n  (let ((rg-align-position-numbers t)\n        (ctx-line-rx \" \\\\{0,4\\\\}[1-9]-\")\n        (match-line-rx (format \" \\\\{0,3\\\\}[0-9]\\\\{1,4\\\\}%s\"\n                               rg-align-position-content-separator))\n        ctx-match line-match)\n    (rg-test-with-first-error\n      (rg-run \"amid\" \"elisp\"\n              (concat default-directory \"test/data\")\n              nil nil '(\"--context=3\"))\n      (forward-line 1)\n      (should (looking-at ctx-line-rx))\n      (setq ctx-match (match-string 0))\n      (forward-line -1)\n      (should (looking-at match-line-rx))\n      (setq line-match (match-string 0))\n      (should (equal (length ctx-match) (length line-match)))\n      (forward-line -1)\n      (should (looking-at ctx-line-rx))\n      (setq ctx-match (match-string 0))\n      (should (equal (length ctx-match) (length line-match))))))\n\n(ert-deftest rg-integration/positions-align-context-line-column ()\n  \"Test line position format with alignment.\"\n  :tags '(need-rg)\n  (let ((rg-show-columns t)\n        (rg-align-position-numbers t)\n        (contex-line-rx \" \\\\{0,9\\\\}[1-9]-\")\n        (match-line-rx (format \" \\\\{0,3\\\\}[0-9]\\\\{1,4\\\\}%s \\\\{0,2\\\\}[0-9]\\\\{1,3\\\\}%s\"\n                               rg-align-line-column-separator\n                               rg-align-position-content-separator))\n        ctx-match line-match)\n    (rg-test-with-first-error\n      (rg-run \"amid\" \"elisp\"\n              (concat default-directory \"test/data\")\n              nil nil '(\"--context=3\"))\n      (forward-line 1)\n      (should (looking-at contex-line-rx))\n      (setq ctx-match (match-string 0))\n      (forward-line -1)\n      (should (looking-at match-line-rx))\n      (setq line-match (match-string 0))\n      (should (equal (length ctx-match) (length line-match)))\n      (forward-line -1)\n      (should (looking-at contex-line-rx))\n      (setq ctx-match (match-string 0))\n      (should (equal (length ctx-match) (length line-match))))))\n\n(ert-deftest rg-integration/navigate-file-group-in-grouped-result ()\n  \"Test file navigation in grouped result.\"\n  :tags '(need-rg)\n  (let ((rg-group-result t)\n        (files '(\"bar.el\" \"foo.el\"))\n        pos)\n    (rg-run \"hello\" \"elisp\" (concat default-directory \"test/data\") nil nil (list \"--sort=path\"))\n    (rg-with-current-result\n      (goto-char (point-min))\n      (rg-navigate-file-group 1)\n      (should (looking-at (concat \"File: \" (car files))))\n      (rg-navigate-file-group 1)\n      (should (looking-at (concat \"File: \" (cadr files))))\n      (compilation-next-error 1)\n      (setq pos (point))\n\n      ;; Move exactly to first match\n      (rg-navigate-file-group -2)\n      (should (looking-at (concat \"File: \" (car files))))\n      (goto-char pos)\n\n      ;; Move past first match should move to first match\n      (rg-navigate-file-group -3)\n      (should (looking-at (concat \"File: \" (car files))))\n\n      ;; rg-navigate-file-group should indicate when it didn't move at all\n      (should-not (rg-navigate-file-group -1)))))\n\n(ert-deftest rg-integration/next-prev-file ()\n  \"Test file navigation in grouped result.\"\n  :tags '(need-rg)\n  (let ((rg-group-result t)\n        (files '(\"bar.el\" \"foo.el\"))\n        pos)\n    (rg-run \"hello\" \"elisp\" (concat default-directory \"test/data\") nil nil (list \"--sort=path\"))\n    (rg-with-current-result\n      (goto-char (point-min))\n      (rg-next-file 1)\n      (forward-line -1)\n      (should (looking-at-p (concat \"File: \" (car files))))\n      (rg-next-file 1)\n      (forward-line -1)\n      (should (looking-at-p (concat \"File: \" (cadr files))))\n      ;; prev from header\n      (rg-prev-file 1)\n      (forward-line -1)\n      (should (looking-at-p (concat \"File: \" (car files))))\n      ;; prev from match\n      (rg-next-file 1)\n      (rg-prev-file 1)\n      (forward-line -1)\n      (should (looking-at-p (concat \"File: \" (car files))))\n      ;; prev from last line\n      (goto-char (- (point-max) 5))\n      (rg-prev-file 1)\n      (forward-line -1)\n      (should (looking-at-p (concat \"File: \" (cadr files))))\n      ;; prev from empty separator line\n      (forward-line 4)\n      (should (looking-at-p \"^$\"))\n      (rg-prev-file 1)\n      (forward-line -1)\n      (should (looking-at-p (concat \"File: \" (cadr files)))))))\n\n(ert-deftest rg-integration/navigate-file-group-in-ungrouped-result ()\n  \"Test file navigation in ungrouped result.\"\n  :tags '(need-rg)\n  (let ((rg-group-result nil))\n    (rg-run \"hello\" \"elisp\" (concat default-directory \"test/data\"))\n    (rg-with-current-result\n      (goto-char (point-min))\n      (rg-navigate-file-group 1)\n      (should (eq (point) (point-min))))))\n\n(defun rg-test-highlight-match (grouped)\n  \"Helper for highlight testing.\nIf GROUPED is is non nil grouped result are used.\"\n  (let ((rg-group-result grouped)\n        pos)\n    (rg-run \"hello\" \"elisp\" (concat default-directory \"test/data\"))\n    (rg-with-current-result\n      (setq pos (rg-single-font-lock-match 'rg-match-face (point-min) (point-max) 1))\n      (should-not (eq (point-max) pos)))))\n\n(ert-deftest rg-integration/highlight-match-group ()\n  \"Test that highlighting of matches works.\"\n  :tags '(need-rg)\n  (rg-test-highlight-match t)\n  (rg-test-highlight-match nil))\n\n(ert-deftest rg-integration/group-result-variable ()\n  \"Test that grouped result is triggered if `rg-group-result' is non nil\nand ungrouped otherwise.\"\n  :tags '(need-rg)\n  (should-not (rg-file-message-exist-in-result nil))\n  (should (rg-file-message-exist-in-result t)))\n\n(ert-deftest rg-integration/rg-recompile ()\n  \"Make sure that `rg-recompile' preserves search parameters.\"\n  :tags '(need-rg)\n  (let ((parent-dir (concat (expand-file-name default-directory) \"test/\")))\n    (rg-run \"hello\" \"elisp\" (concat parent-dir \"data\"))\n    (rg-with-current-result\n      (cl-letf (((symbol-function #'rg-read-pattern) #'ignore))\n        (setf (rg-search-files rg-cur-search) \"all\")\n        (setf (rg-search-pattern rg-cur-search) \"Hello\")\n        (setf (rg-search-dir rg-cur-search) parent-dir)\n        (setf (rg-search-flags rg-cur-search) '(\"--text\"))\n        (rg-rerun))\n        (should (rg-wait-for-search-result))\n        (should (equal\n                 (list \"Hello\" \"all\" parent-dir)\n                 (list (rg-search-pattern rg-cur-search)\n                       (rg-search-files rg-cur-search)\n                       (rg-search-dir rg-cur-search))))\n        (should (equal '(\"--text\") (rg-search-flags rg-cur-search)))\n        (rg-recompile)\n        (should (rg-wait-for-search-result))\n        (should (equal\n                 (list \"Hello\" \"all\" parent-dir)\n                 (list (rg-search-pattern rg-cur-search)\n                       (rg-search-files rg-cur-search)\n                       (rg-search-dir rg-cur-search))))\n        (should (equal '(\"--text\") (rg-search-flags rg-cur-search))))))\n\n(ert-deftest rg-integration/display-exit-message ()\n  \"Verify exit messages.\"\n  :tags '(need-rg)\n  (rg-run \"foo\" \"*.baz\" (concat default-directory \"test/data\"))\n  (with-current-buffer (rg-buffer-name)\n    (rg-wait-for-search-result)\n    (s-matches-p \"no matches found\" (buffer-substring-no-properties (point-min) (point-max))))\n  (rg-run \"hello\" \"*.baz\" (concat default-directory \"test/data\"))\n  (rg-with-current-result\n    (should (equal rg-hit-count 6))\n    (s-matches-p \"(6 matches found)\" (buffer-substring-no-properties (point-min) (point-max)))))\n\n(ert-deftest rg-integration/list-searches ()\n  \"Test `rg-list-searches'.\"\n  :tags '(need-rg)\n  (rg-run \"hello\" \"all\" (concat default-directory \"test/data\"))\n  (rg-with-current-result\n   (rg-list-searches)\n   (with-current-buffer rg-search-list-buffer-name\n     (ibuffer-forward-line)\n     (search-forward \"hello\"))\n   (kill-buffer rg-search-list-buffer-name)))\n\n(ert-deftest rg-integration/run-confirm-unchanged-command ()\n  \"Test confirm and full command search\"\n  :tags '(need-rg)\n  (cl-letf* ((rg-history nil)\n             (called-prompt nil)\n             (called-history nil)\n             ((symbol-function #'read-from-minibuffer)\n              (lambda (prompt command _ign1 _ign2 history)\n                (setq called-prompt prompt)\n                (setq called-history history)\n                command)))\n    (rg-run \"hello\" \"all\" \"tmp/test\" nil 'confirm)\n    (rg-with-current-result\n      (should (eq called-history 'rg-history))\n      (should (equal called-prompt \"Confirm: \"))\n      (should-not (null rg-cur-search))\n      ;; We use the stub about which does not update the history\n      (should (null rg-history)))))\n\n(ert-deftest rg-integration/run-confirm-changed-command ()\n  \"Test confirm and full command search\"\n  :tags '(need-rg)\n  (cl-letf* ((rg-history nil)\n             (changed-command nil)\n             (original-command nil)\n             ((symbol-function #'read-from-minibuffer)\n              (lambda (_ign1 command _ign2 _ign3 _ign4)\n                (setq changed-command (concat command \"\\\\ world\"))\n                (setq original-command command)\n                changed-command)))\n    (rg-run \"hello\" \"all\" \"tmp/test\" nil 'confirm)\n    (rg-with-current-result\n      (should (equal changed-command (concat original-command \"\\\\ world\")))\n      (should (rg-search-full-command rg-cur-search))\n      ;; We use the stub above which does not update the history\n      (should (null rg-history)))))\n\n(ert-deftest rg-integration/dwim-search ()\n  \"Test `rg-dwim'.\"\n  (cl-letf* ((called-pattern nil)\n             (called-files nil)\n             (called-dir nil)\n             (called-literal nil)\n             (project-dir (expand-file-name default-directory))\n             ((symbol-function #'rg-run)\n              (lambda (pattern files dir &optional literal &rest _)\n                (setq called-pattern pattern)\n                (setq called-files files)\n                (setq called-dir dir)\n                (setq called-literal literal))))\n    (find-file \"test/data/foo.el\")\n    (rg-dwim)\n    (should (equal called-pattern \"hello\"))\n    (should (equal called-files \"elisp\"))\n    (should (equal (expand-file-name called-dir) project-dir))\n    (should-not (eq called-literal nil))\n    (rg-dwim '(4))\n    (should (equal (expand-file-name called-dir) (expand-file-name default-directory)))\n    (rg-dwim '(16))\n    (should (equal called-files \"foo.el\"))))\n\n(ert-deftest rg-integration/project-search ()\n  \"Test `rg-project'.\"\n  (cl-letf* ((called-pattern nil)\n             (called-files nil)\n             (called-dir nil)\n             (called-literal nil)\n             (project-dir (expand-file-name default-directory))\n             ((symbol-function #'rg-run)\n              (lambda (pattern files dir &optional literal &rest _)\n                (setq called-pattern pattern)\n                (setq called-files files)\n                (setq called-dir dir)\n                (setq called-literal literal))))\n    (find-file \"test/data/foo.baz\")\n    (rg-project \"hello\" \"elisp\")\n    (should (equal called-pattern \"hello\"))\n    (should (equal called-files \"elisp\"))\n    (should (equal (expand-file-name called-dir) project-dir))\n    (should (eq called-literal nil))))\n\n\n(defun rg-only-rg-regexps-p ()\n  (and (seq-every-p\n        (lambda (elem) (eq elem t))\n        (mapcar (lambda (regexp)\n                  (s-starts-with-p \"rg-\" (symbol-name regexp)))\n                compilation-error-regexp-alist))\n       (seq-every-p\n        (lambda (elem) (eq elem t))\n        (mapcar (lambda (pair)\n                  (s-starts-with-p \"rg-\" (symbol-name (car pair))))\n                compilation-error-regexp-alist-alist))))\n\n(ert-deftest rg-integration/compilation-error-regexp ()\n  \"Test that compilation-error-regexp-alist is only using rg regexps.\"\n  (with-temp-buffer\n    (rg-mode)\n    (should (rg-only-rg-regexps-p)))\n  (with-temp-buffer\n    (setq compilation-error-regexp-alist '(foo-bar))\n    (rg-mode)\n    (should (rg-only-rg-regexps-p)))\n  (with-temp-buffer\n    (add-hook 'compilation-mode-hook\n              (lambda ()\n                (setq compilation-error-regexp-alist '(foo-bar))))\n    (rg-mode)\n    (should (rg-only-rg-regexps-p))))\n\n(ert-deftest rg-integration/rg-executable-per-connection ()\n  \"Disabling setting should disable connection local variable.\"\n  (skip-unless (version<= \"27\" emacs-version))\n  (rg-with-executable-find-mock\n   (let ((rg-executable-per-connection nil)\n         (connection-local-profile-alist '())\n         (default-directory\n           (format \"/sudo:%s@localhost:%s\" (user-login-name) default-directory)))\n     (with-temp-buffer\n       (should (equal (rg-executable) \"local-rg\"))))))\n\n(ert-deftest rg-integration/rg-executable-local-notfound ()\n  \"Test error if local exeutable not found.\"\n  (rg-with-executable-find-mock\n   (let ((rg-executable nil)\n         (default-directory \"/tmp\"))\n     (with-temp-buffer\n       (should-error (rg-executable))))))\n\n(ert-deftest rg-integration/rg-executable-local ()\n  \"Local buffer should get local executable.\"\n  (rg-with-executable-find-mock\n    (let ((connection-local-profile-alist '()))\n      (with-temp-buffer\n        (should (equal (rg-executable) \"local-rg\"))))))\n\n(ert-deftest rg-integration/rg-executable-remote-notfound ()\n  \"Test error if remote exeutable not found.\"\n  (skip-unless (version<= \"27\" emacs-version))\n  (cl-letf (((symbol-function #'executable-find)\n             (lambda (command &rest) nil))\n            (connection-local-profile-alist '())\n            (default-directory\n              (format \"/sudo:%s@localhost:%s\"\n                      (user-login-name) default-directory)))\n    (with-temp-buffer\n      (should-error (rg-executable)))))\n\n\n(ert-deftest rg-integration/rg-executable-through-rg-run ()\n  \"Correct executable should be trigggered through main entry points.\"\n  (skip-unless (version<= \"27\" emacs-version))\n  (rg-with-executable-find-mock\n    (cl-letf* ((connection-local-profile-alist '())\n               (result nil)\n               ((symbol-function #'compilation-start)\n                (lambda (command &rest _)\n                  (setq result command)\n                  (let ((buffer (get-buffer-create \"*rg-temp*\")))\n                    (with-current-buffer buffer\n                      (rg-mode))\n                    buffer))))\n      (with-temp-buffer\n        (rg-run \"pattern\" \"all\" \"/tmp\")\n        (should (string-prefix-p \"local-rg\" result)))\n      (with-temp-buffer\n        (rg-run \"pattern\" \"all\"\n                (format \"/sudo:%s@localhost:%s\"\n                        (user-login-name) default-directory))\n        (should (string-prefix-p \"remote-rg-localhost\" result))))))\n\n(ert-deftest rg-integration/rg-executable-remote-new-buffers ()\n  \"Once set the remote executable should be applied to new buffers for the same host.\"\n  (skip-unless (version<= \"27\" emacs-version))\n  (rg-with-executable-find-mock\n    (let ((default-directory\n            (format \"/sudo:%s@localhost:%s\" (user-login-name) default-directory))\n          (connection-local-profile-alist '()))\n      (with-temp-buffer\n        (should (equal (rg-executable) \"remote-rg-localhost\")))\n      (with-temp-buffer\n        (should (equal (rg-executable) \"remote-rg-localhost\"))))))\n\n(ert-deftest rg-integration/rg-executable-remote-open-buffers ()\n  \"Once set the remote executable should be applied to already open buffers for the same host.\"\n  (skip-unless (version<= \"27\" emacs-version))\n  (rg-with-executable-find-mock\n    (let ((connection-local-profile-alist '())\n          (default-directory\n            (format \"/sudo:%s@localhost:%s\"\n                    (user-login-name) default-directory)))\n      (with-temp-buffer\n        (with-temp-buffer\n          (should (equal (rg-executable) \"remote-rg-localhost\")))\n        (should (equal (rg-executable) \"remote-rg-localhost\"))))))\n\n(ert-deftest rg-integration/rg-executable-remote-multiple-hosts ()\n  \"Different hosts should get get remote specific binary.\"\n  (skip-unless (version<= \"27\" emacs-version))\n  (rg-with-executable-find-mock\n    (let ((connection-local-profile-alist '()))\n      (let ((default-directory\n              (format \"/sudo:%s@localhost:%s\"\n                      (user-login-name) default-directory)))\n        (with-temp-buffer\n          (should (equal (rg-executable) \"remote-rg-localhost\"))))\n\n      (let ((default-directory\n              (format \"/sudo:%s@127.0.0.1:%s\"\n                      (user-login-name) default-directory)))\n        (with-temp-buffer\n          (should (equal (rg-executable) \"remote-rg-127.0.0.1\")))))))\n\n(ert-deftest rg-integration/rg-executable-remote-and-local ()\n  \"Remote host get remote executable and local host get local executable.\"\n  (skip-unless (version<= \"27\" emacs-version))\n  (rg-with-executable-find-mock\n    (let ((connection-local-profile-alist '()))\n      (let ((default-directory\n              (format \"/sudo:%s@localhost:%s\" (user-login-name) default-directory)))\n        (with-temp-buffer\n          (should (equal (rg-executable) \"remote-rg-localhost\"))\n          (let ((default-directory \"/tmp\"))\n            (should (equal (rg-executable) \"local-rg\"))))))))\n\n(ert-deftest rg-integration/rg-executable-results-buffer ()\n  \"Correct executable should be trigggered from results buffer.\"\n  (skip-unless (version<= \"27\" emacs-version))\n  (rg-with-executable-find-mock\n    (let ((connection-local-profile-alist '()))\n      (with-temp-buffer\n        (rg-run \"pattern\" \"all\" \"/tmp\")\n        (rg-with-current-result\n          (should (string-prefix-p \"local-rg\" (car compilation-arguments)))\n          (setf (rg-search-dir rg-cur-search)\n                (format \"/sudo:%s@localhost:%s\"\n                        (user-login-name) default-directory))\n          (rg-rerun)\n          (rg-wait-for-search-result)\n          (should (string-prefix-p \"remote-rg-localhost\"\n                                   (car compilation-arguments)))\n          (setf (rg-search-dir rg-cur-search) \"/tmp\")\n          (rg-rerun)\n          (rg-wait-for-search-result)\n          (should (string-prefix-p \"local-rg\" (car compilation-arguments))))))))\n\n(ert-deftest rg-integration/default-directory-search-from-results ()\n  \"Verify default-directory when doing a search from results buffer.\"\n  :tags '(need-rg)\n  (let ((search-dir1 (expand-file-name default-directory))\n        (search-dir2 (file-name-directory\n                      (expand-file-name\n                       (concat default-directory \"test/data\")))))\n    (rg-run \"foo\" \"*.baz\" search-dir1)\n    (with-current-buffer (rg-buffer-name)\n      (should (equal default-directory search-dir1))\n      (rg-wait-for-search-result)\n      (rg-run \"foo\" \"*.baz\" search-dir2)\n      (should (equal default-directory search-dir2))\n      (rg-wait-for-search-result))))\n\n(provide 'rg.el-test)\n\n;;; rg.el-test.el ends here\n"
  },
  {
    "path": "test/style-check.el",
    "content": ";;; style-check.el --- rg.el: Check emacs lisp style of package files\n\n;; Copyright (C) 2017 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;;; Code:\n\n(require 'flycheck)\n(require 'package-lint)\n(load \"test-helper\")\n\n(defun rg-message ())\n\n(defun get-compilation-buffer ()\n  (let (buffer)\n    (dolist (buf (buffer-list) buffer)\n      (when (eq (with-current-buffer buf major-mode) 'compilation-mode)\n        (setq buffer buf)))))\n\n(defun run-flycheck (checker)\n  (flycheck-compile checker)\n  (let ((buffer (get-compilation-buffer)))\n    (unless buffer\n      (error \"No compilation buffer\"))\n    (with-current-buffer buffer\n      (rg-wait-for-search-result)\n      (goto-char (point-min))\n      (let (beg error-lines)\n        (while (ignore-errors (compilation-next-error 1))\n          (setq beg (point))\n          (end-of-line)\n          (push (buffer-substring-no-properties beg (point)) error-lines))\n        (when error-lines\n          (rg-message \"%s\" (mapconcat 'identity\n                                      (reverse error-lines) \"\\n\"))\n          (kill-emacs 2))))))\n\n(defun run-emacs-lisp-flycheck-and-exit ()\n  (cl-letf (((symbol-function #'rg-message) (symbol-function #'message))\n            ((symbol-function #'message) #'ignore)\n            (flycheck-emacs-lisp-load-path 'inherit))\n     (dolist (file argv)\n      (dolist (checker '(emacs-lisp-checkdoc emacs-lisp))\n        (with-temp-buffer\n          (insert-file-contents file t)\n          (emacs-lisp-mode)\n          (run-flycheck checker)))))\n  (kill-emacs 0))\n\n(defun run-package-lint-and-exit ()\n  (setq package-user-dir \"/tmp/rg-elpa\")\n  (add-to-list 'package-archives '(\"melpa\" . \"http://melpa.org/packages/\") t)\n  (package-refresh-contents)\n  (package-lint-batch-and-exit))\n\n;;; style-check.el ends here\n"
  },
  {
    "path": "test/test-helper.el",
    "content": ";;; test-helper.el --- rg.el: Helper for tests\n\n;; Copyright (C) 2017 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;;; Code:\n\n(when (require 'undercover nil t)\n  (undercover \"*.el\"\n              (:report-format 'lcov)\n              (:send-report nil)))\n\n(require 'cl-lib)\n(require 'ert)\n(require 'rg)\n(require 'rg-history)\n(require 'rg-isearch)\n(require 'rg-menu)\n(require 's)\n(require 'seq)\n(require 'tramp)\n(require 'wgrep-rg)\n(require 'mule-util)\n\n(defun rg-regexp-anywhere (needle)\n  (s-replace \"%%%%\" needle \"\\\\( \\\\|^\\\\)%%%%\\\\( \\\\|$\\\\)\"))\n\n(defun rg-regexp-last (needle)\n  (s-replace \"%%%%\" needle \"\\\\( \\\\|^\\\\)%%%%$\"))\n\n(defun rg-regexp-anywhere-but-last (needle)\n  (s-replace \"%%%%\" needle \"\\\\( \\\\|^\\\\)%%%% \"))\n\n(defun rg-run-and-wait (fn &rest args)\n  \"Run FN  with ARGS and then wait for search to be done.\"\n  (apply fn args)\n  (with-current-buffer (rg-buffer-name)\n    (rg-wait-for-search-result)))\n\n(defun rg-wait-for-search-result ()\n  \"Wait for the rg process to finish searching and return non nil if the\nsearch was successful. Timeout is 10 s.\"\n  (let (search-finished)\n    (add-hook 'compilation-finish-functions\n              (lambda (buffer msg) (setq search-finished msg))\n              t t)\n    (with-timeout (10 nil)\n      (while (not search-finished)\n        (accept-process-output nil 0.1)))\n    (when search-finished\n      (equal (string-trim search-finished) \"finished\"))))\n\n(defun rg-check-git-project-root ()\n\"Check that project root of rg.el-test.el file is main dir of\nrepository.\"\n  (should (equal\n           (expand-file-name (rg-project-root\n                              (concat default-directory \"/test/rg.el-test.el\")))\n           (expand-file-name default-directory))))\n\n(defmacro rg-with-current-result (&rest body)\n  \"Evaluate BODY in current result buffer when search has finished.\"\n  (declare (indent 0) (debug t))\n  `(with-current-buffer (rg-buffer-name)\n     (font-lock-ensure)\n     (rg-wait-for-search-result)\n     (let ((result (progn ,@body)))\n       (kill-buffer)\n       result)))\n\n(defmacro rg-with-temp-global-keymap (&rest body)\n  \"Evaluate BODY with a temporary keymap as global map.\nRestore original global keymap afterwards.\"\n  (declare (indent 0) (debug t))\n  (let ((saved-global-map (cl-gensym))\n        (temp-global-map (cl-gensym)))\n    `(let ((,saved-global-map (current-global-map))\n           (,temp-global-map (make-sparse-keymap)))\n       (use-global-map ,temp-global-map)\n       ,@body\n       (use-global-map ,saved-global-map))))\n\n(defmacro rg-test-with-fontified-buffer (search &rest body)\n  \"Run SEARCH and make sure buffer is fontified when executing BODY.\nSEARCH can either be a search string or a form invocating `rg-run'.\"\n  (declare (indent 1) (debug t))\n  (let ((invocation\n         (if (stringp search)\n             `(rg-run ,search \"elisp\" (concat default-directory \"test/data\"))\n           search)))\n    (cl-assert (consp invocation))\n    `(progn\n       ,invocation\n       (rg-with-current-result\n         ;; font-lock-mode is disabled by default in batch mode so\n         ;; request explicit fontification\n         (font-lock-ensure)\n         ,@body))))\n\n(defmacro rg-test-with-command-start (search &rest body)\n  \"Run search and put point to beginning of rg command when running BODY.\"\n  (declare (indent 0) (debug t))\n  (let ((command-start (cl-gensym)))\n    `(rg-test-with-fontified-buffer ,search\n       (let ((,command-start (next-single-property-change (point-min) 'rg-command-hidden-part)))\n         (should ,command-start)\n         (should-not (eq ,command-start (point-max)))\n         (goto-char ,command-start)\n         ,@body))))\n\n(defmacro rg-test-with-first-error (search &rest body)\n  \"Run search and put point at start of first error line when running BODY.\"\n  (declare (indent 0) (debug t))\n  `(rg-test-with-fontified-buffer ,search\n     (compilation-next-error 1)\n     (should-not (eq (point) (point-max)))\n     (beginning-of-line)\n     ,@body))\n\n(defmacro rg-with-executable-find-mock (&rest body)\n  \"Mock `executable-find' in BODY.\"\n  (declare (indent 0) (debug t))\n  `(cl-letf* (((symbol-function #'executable-find)\n               (lambda (command &optional remote)\n                 (let ((tramp-name (tramp-dissect-file-name default-directory)))\n                   (concat \"remote-rg-\" (tramp-file-name-host-port tramp-name)))))\n              (rg-executable \"local-rg\"))\n     ,@body))\n\n(defun simulate-rg-run (pattern files dir)\n  (setq-default rg-cur-search\n                (rg-search-create\n                 :pattern pattern\n                 :files files\n                 :flags rg-initial-toggle-flags)))\n\n(defun rg-file-message-exist-in-result (grouped)\n  \"Search and return non nil if 'rg-file-tag-face exist in buffer.\nGROUPED control if `rg-group-result' is used.\"\n  (let((rg-group-result grouped)\n       pos)\n    (rg-run \"hello\" \"elisp\" (concat default-directory \"test/data\"))\n    (rg-with-current-result\n      (not (eq (point-max) (next-single-property-change (point-min)\n                                             'rg-file-message\n                                             nil (point-max)))))))\n\n(defun rg-single-font-lock-match (face pos limit direction)\n  \"Return position of next match of 'font-lock-face property that equals FACE.\nPOS is the start position of the search and LIMIT is the limit of the\nsearch.  If FACE is not found within LIMIT, LIMIT is returned.  If\nDIRECTION is positive search forward in the buffer, otherwise search\nbackward.\"\n  (let ((single-property-change-func\n         (if (> direction 0)\n             'next-single-property-change\n           'previous-single-property-change)))\n    (while\n        (progn\n          (setq pos (funcall single-property-change-func pos 'font-lock-face nil limit))\n          (and (not (equal pos limit))\n               (not (let ((properties (get-text-property pos 'font-lock-face)))\n                      (if (listp properties)\n                          (member face properties)\n                        (eq face properties))))))))\n  pos)\n\n(defun rg-set-equal-p (set1 set2)\n  \"Compare if SET1 and SET2 contain the same elements.\"\n  (not (cl-set-exclusive-or set1 set2 :test #'equal)))\n\n(defun rg-truncate-string-ellipsis ()\n  (if (fboundp 'truncate-string-ellipsis)\n      (truncate-string-ellipsis)\n    truncate-string-ellipsis))\n\n;;; test-helper.el ends here\n"
  },
  {
    "path": "test/wgrep-rg.el-test.el",
    "content": ";;; wgrep-rg.el-test.el --- wgrep-rg.el tests -*- lexical-binding: t; -*-\n\n;; Copyright (C) 2018 David Landell <david.landell@sunnyhill.email>\n;;\n;; Author: David Landell <david.landell@sunnyhill.email>\n;; URL: https://github.com/dajva/rg.el\n\n;; This file is not part of GNU Emacs.\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n;; 02110-1301, USA.\n\n;;; Commentary:\n\n;;; Code:\n\n\f\n;; Integration tests\n\n(ert-deftest rg-integration-test/wgrep-nogroup ()\n  \"wgrep test with grouped result.\"\n  :tags '(need-rg)\n  (let ((rg-show-columns nil)\n        (rg-group-result nil)\n        (rg-align-position-numbers nil))\n    (rg-run-wgrep-tests)\n    (rg-run-wgrep-context-tests)))\n\n(ert-deftest rg-integration-test/wgrep-nogroup-columns ()\n  \"wgrep test with grouped result.\"\n  :tags '(need-rg)\n  (let ((rg-show-columns t)\n        (rg-group-result nil)\n        (rg-align-position-numbers nil))\n    (rg-run-wgrep-tests)\n    (rg-run-wgrep-context-tests)))\n\n(ert-deftest rg-integration-test/wgrep-group ()\n  \"wgrep test with grouped result.\"\n  :tags '(need-rg)\n  (let ((rg-show-columns nil)\n        (rg-group-result t)\n        (rg-align-position-numbers nil))\n    (rg-run-wgrep-tests)\n    (rg-run-wgrep-context-tests)))\n\n(ert-deftest rg-integration-test/wgrep-group-columns ()\n  \"wgrep test with grouped result.\"\n  :tags '(need-rg)\n  (let ((rg-show-columns t)\n        (rg-group-result t)\n        (rg-align-position-numbers nil))\n    (rg-run-wgrep-tests)\n    (rg-run-wgrep-context-tests)))\n\n(ert-deftest rg-integration-test/wgrep-group-align ()\n  \"wgrep test with aligned and grouped result.\"\n  :tags '(need-rg)\n  (let ((rg-show-columns nil)\n        (rg-group-result t)\n        (rg-align-position-numbers t))\n    (rg-run-wgrep-tests)\n    (rg-run-wgrep-context-tests)))\n\n(ert-deftest rg-integration-test/wgrep-group-align-columns ()\n  \"wgrep test with aligned and grouped result including column numbers.\"\n  :tags '(need-rg)\n  (let ((rg-show-columns t)\n        (rg-group-result t)\n        (rg-align-position-numbers t))\n    (rg-run-wgrep-tests)\n    (rg-run-wgrep-context-tests)))\n\n(ert-deftest rg-integration-test/wgrep-group-align-columns-custom-separators ()\n  \"wgrep test with aligned and grouped result including column numbers.\"\n  :tags '(need-rg)\n  (let ((rg-show-columns t)\n        (rg-group-result t)\n        (rg-align-position-numbers t)\n        (rg-align-line-column-separator \"   \")\n        (rg-align-position-content-separator \"#\"))\n    (rg-run-wgrep-tests)\n    (rg-run-wgrep-context-tests)))\n\n\f\n;; Helper functions\n\n(defun rg-check-wgrep-header ()\n  (goto-char (point-min))\n  (should (get-text-property (point) 'wgrep-header))\n  ;; Jump over \"rg-started\" line that could match error regexp.\n  (goto-char (next-single-property-change (point-min) 'rg-command-hidden-part))\n  (should (get-text-property (point) 'wgrep-header))\n  (end-of-line)\n  (should (get-text-property (point) 'wgrep-header))\n  (rg-next-file 1)\n  (should-not (get-text-property (point) 'wgrep-header)))\n\n(defun rg-check-wgrep-footer ()\n  (goto-char (1- (point-max)))\n  (should (get-text-property (point) 'wgrep-footer))\n  ;; \"rg finished\" line sometimes match error regexp so skip that.\n  (forward-line -1)\n  (compilation-previous-error 1)\n  (should-not (get-text-property (point) 'wgrep-footer))\n  (re-search-forward \"^$\")\n  (should (get-text-property (point) 'wgrep-footer)))\n\n(defun rg-check-wgrep-props-at-pos (pos)\n  (let ((wgrep-expected-props '(wgrep-line-filename wgrep-line-number))\n        (all-props (text-properties-at pos)))\n    (dolist (expected wgrep-expected-props)\n      (should (member expected all-props)))))\n\n(defun rg-check-no-wgrep-prop-at-pos (pos)\n  (let ((wgrep-expected-props '(wgrep-line-filename wgrep-line-number))\n        (all-props (text-properties-at pos)))\n    (dolist (expected wgrep-expected-props)\n      (should-not (member expected all-props)))))\n\n(defun rg-check-wgrep-current-line ()\n  (rg-check-wgrep-props-at-pos (point))\n  (should (get-text-property (point) 'read-only))\n  (end-of-line)\n  (backward-char)\n  (rg-check-no-wgrep-prop-at-pos (point))\n  (should-not (get-text-property (point) 'read-only)))\n\n(defun rg-move-to-context-line ()\n  (goto-char (point-min))\n  ;; Jump over \"rg-started\" line that could match error regexp.\n  (goto-char (next-single-property-change (point-min) 'rg-command-hidden-part))\n  (compilation-next-file 1)\n  (forward-line -1))\n\n(defun rg-run-wgrep-context-tests ()\n  (rg-test-with-fontified-buffer\n      (rg-run \"amid\" \"elisp\"\n              (concat default-directory \"test/data\")\n              nil nil '(\"--context=3\"))\n    (wgrep-change-to-wgrep-mode)\n    (rg-check-wgrep-current-buffer)\n    (rg-move-to-context-line)\n    (rg-check-wgrep-current-line)))\n\n(defun rg-run-wgrep-tests()\n  (rg-test-with-fontified-buffer \"hello\"\n    (wgrep-change-to-wgrep-mode)\n    (rg-check-wgrep-current-buffer)))\n\n(defun rg-check-wgrep-current-buffer ()\n  (rg-check-wgrep-header)\n  (rg-check-wgrep-footer)\n\n  (goto-char (point-min))\n  ;; Jump over \"rg-started\" line that could match error regexp.\n  (goto-char (next-single-property-change (point-min) 'rg-command-hidden-part))\n  (compilation-next-file 1)\n  (rg-check-wgrep-current-line)\n\n  (goto-char (point-max))\n  ;; \"rg finished\" line sometimes match error regexp so skip that.\n  (forward-line -1)\n  (compilation-previous-error 1)\n  (rg-check-wgrep-current-line))\n\n(provide 'wgrep-rg.el-test)\n\n;;; wgrep-rg.el-test.el ends here\n"
  },
  {
    "path": "wgrep-rg.el",
    "content": ";;; wgrep-rg.el --- Writable rg buffer and apply the changes to files -*- lexical-binding: t; -*-\n\n;; Author: Masahiro Hayashi <mhayashi1120@gmail.com>\n;; Rewritten by: Dale Sedivec <dale@codefu.org>\n;; Maintainer: David Landell <david.landell@sunnyhill.email>\n;; Keywords: grep edit extensions\n;; URL: http://github.com/dajva/rg.el\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License as\n;; published by the Free Software Foundation; either version 3, or (at\n;; your option) any later version.\n\n;; This program is distributed in the hope that it will be useful, but\n;; WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n;; General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with GNU Emacs; see the file COPYING.  If not, write to the\n;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\n;; Boston, MA 02110-1301, USA.\n\n;;; Commentary:\n\n;; wgrep-rg allows you to edit a rg buffer and apply those changes to\n;; the file buffer.\n\n;;; Install:\n\n;; 1. Install rg.el\n;;\n;;   https://github.com/dajva/rg.el\n\n;; 2. Install wgrep.el\n\n;; 3. Put this file into load-path'ed directory, and byte compile it if\n;; desired. And put the following expression into your ~/.emacs.\n;;\n;;     (autoload 'wgrep-rg-setup \"wgrep-rg\")\n;;     (add-hook 'rg-mode-hook 'wgrep-rg-setup)\n\n;;; Usage:\n\n;; See wgrep.el\n\n;;; Code:\n\n(require 'wgrep)\n\n;; Forward declarations\n(declare-function rg-file-line-column-pattern-group \"rg-result.el\")\n(declare-function rg-file-line-pattern-group \"rg-result.el\")\n(defvar rg-mode-hook)\n\n(defvar wgrep-rg-grouped-result-file-regexp \"^File:[[:space:]]+\\\\(.*\\\\)$\"\n  \"Regular expression for the start of results for a file in grouped results.\n\\\"Grouped results\\\" are what you get from rg.el when\n`rg-group-result' is true or when you call rg with --heading.\")\n\n(defvar wgrep-rg-ungrouped-result-regexp\n  \"^\\\\(.+?\\\\)\\\\(?:-\\\\|:\\\\)\\\\([1-9][0-9]*\\\\)\\\\(?:-\\\\|:\\\\)\\\\(?:[1-9][0-9]*:\\\\)*\"\n  \"Regular expression for an ungrouped result.\nYou get \\\"ungrouped results\\\" when `rg-group-result' is false or\nwhen you manage to call rg with --no-heading.\")\n\n(defun wgrep-rg-prepare-header/footer ()\n  \"Add wgrep related text properties for header and footer.\nThis is needed in order for wgrep to ignore thos areas when parsing\nthe content.\"\n  (save-excursion\n    (goto-char (point-min))\n    ;; Look for the first useful result line.\n    (let ((result-line-regexp (concat wgrep-rg-grouped-result-file-regexp\n                                      \"\\\\|\"\n                                      wgrep-rg-ungrouped-result-regexp)))\n      (while\n          (progn\n            (if (not (re-search-forward result-line-regexp nil t))\n                ;; No results in this buffer, let's mark the whole thing as\n                ;; header.\n                (progn\n                  (add-text-properties (point-min) (point-max)\n                                       '(read-only t wgrep-header t))\n                  nil)\n              (save-excursion\n                (beginning-of-line)\n                ;; The ungrouped result regexp also match the \"rg started\"\n                ;; line. If that happens continue searching.\n                (if (looking-at-p \"rg started.*\")\n                    'continue\n                  (add-text-properties (point-min) (point)\n                                       '(read-only t wgrep-header t))\n                  nil)))))\n        (goto-char (point-max))\n        (re-search-backward \"^rg finished .*$\" nil t)\n        ;; Move to the start of the line after the last result, and\n        ;; mark everything from that line forward as wgrep-footer.\n        (when (zerop (forward-line -1))\n          (add-text-properties (point) (point-max)\n                               '(read-only t wgrep-footer t))))))\n\n(defun wgrep-rg-parse-command-results ()\n  \"Parse the rg results for wgrep usage.\nThis makes non content of the buffer readonly and marks specific areas\nwith wgrep text properties to allow for wgrep to do its job.\"\n  ;; Note that this function is called with the buffer narrowed to\n  ;; exclude the header and the footer.  (We're going to assert that\n  ;; fact here, because we use (bobp) result a bit further down to\n  ;; decide that we're not reading grouped results; see below.)\n  (unless (bobp)\n    (error \"Expected to be called with point at beginning of buffer\"))\n  (save-excursion\n    ;; First look for grouped results (`rg-group-result' is/was\n    ;; probably true).\n    (while (re-search-forward wgrep-rg-grouped-result-file-regexp nil t)\n      ;; Ignore the line that introduces matches from a file, so that\n      ;; wgrep doesn't let you edit it.\n      (add-text-properties (match-beginning 0) (match-end 0)\n                           '(wgrep-ignore t))\n      (let ((file-name (match-string-no-properties 1)))\n        ;; Note that I think wgrep uses this property to quickly find\n        ;; the file it's interested in when searching during some\n        ;; operation(s).  We stick it on the file name in the results\n        ;; group header.\n        (add-text-properties (match-beginning 1) (match-end 1)\n                             (list (wgrep-construct-filename-property file-name)\n                                   file-name))\n        ;; Matches are like: 999{separator}55{separator}line content here\n        ;; Context lines are like: 999-line content here\n        (while (and\n                (zerop (forward-line 1)) ; last line\n                (not (looking-at-p \"^$\"))) ; Empty line between files\n          (cond ((or (looking-at (rg-file-line-column-pattern-group))\n                     (looking-at (rg-file-line-pattern-group))\n                     ;; Context lines\n                     (looking-at \"^ *\\\\([1-9][0-9]*\\\\)-\"))\n                 (add-text-properties (match-beginning 0) (match-end 0)\n                                      (list 'wgrep-line-filename file-name\n                                            'wgrep-line-number\n                                            (string-to-number (match-string 1)))))\n                ;; Ignore context separator.\n                ((looking-at \"^--$\")\n                 (add-text-properties (match-beginning 0) (match-end 0)\n                                      '(wgrep-ignore t)))))))\n    (when (bobp)\n      ;; Search above never moved point, so match non-grouped results\n      ;; (`rg-group-result' is/was probably false).\n      (let (last-file-name)\n        ;; Matches are like: /foo/bar:999:55:line content here\n        ;; Context lines are like: /foo/bar-999-line content here\n        (while (re-search-forward (concat wgrep-rg-ungrouped-result-regexp\n                                          \"\\\\|\\\\(^--$\\\\)\")\n                                  nil t)\n          (if (match-beginning 3)\n              ;; Ignore context separator.\n              (add-text-properties (match-beginning 0) (match-end 0)\n                                   '(wgrep-ignore t))\n            (let ((file-name (match-string-no-properties 1))\n                  (line-number (string-to-number (match-string 2))))\n              (unless (equal file-name last-file-name)\n                ;; This line is a result from a different file than\n                ;; the last match (or else this is the first match in\n                ;; the results).  Write the special file name property\n                ;; for wgrep.\n                (let ((file-name-prop\n                       (wgrep-construct-filename-property file-name)))\n                  (add-text-properties (match-beginning 1) (match-end 1)\n                                       (list file-name-prop file-name)))\n                (setq last-file-name file-name))\n              (add-text-properties (match-beginning 0) (match-end 0)\n                                   (list 'wgrep-line-filename file-name\n                                         'wgrep-line-number line-number)))))))))\n\n;;;###autoload\n(defun wgrep-rg-setup ()\n  \"Setup wgrep rg support.\"\n  (set (make-local-variable 'wgrep-header&footer-parser)\n       'wgrep-rg-prepare-header/footer)\n  (set (make-local-variable 'wgrep-results-parser)\n       'wgrep-rg-parse-command-results)\n  (wgrep-setup-internal))\n\n(defun wgrep-rg-warn-ag-setup ()\n  \"Print warning message if old ag setup is used.\"\n  (when (memq 'wgrep-ag-setup rg-mode-hook)\n    (message \"Warning: wgrep-ag is no longer supported by this package. Please remove wgrep-ag-setup from rg-mode-hook.\")))\n\n;;;###autoload\n(add-hook 'rg-mode-hook 'wgrep-rg-setup)\n\n;; For `unload-feature'\n(defun wgrep-rg-unload-function ()\n  \"Allow for unloading wgrep rg support.\"\n  (remove-hook 'rg-mode-hook 'wgrep-rg-setup))\n\n(provide 'wgrep-rg)\n\n;;; wgrep-rg.el ends here\n"
  }
]