rgapi 0.1.28__tar.gz → 0.1.29__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -330,7 +330,7 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
330
330
 
331
331
  [[package]]
332
332
  name = "rgapi"
333
- version = "0.1.28"
333
+ version = "0.1.29"
334
334
  dependencies = [
335
335
  "crc32fast",
336
336
  "globset",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rgapi"
3
- version = "0.1.28"
3
+ version = "0.1.29"
4
4
  edition = "2024"
5
5
  rust-version = "1.91"
6
6
  license = "Apache-2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rgapi
3
- Version: 0.1.28
3
+ Version: 0.1.29
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Requires-Dist: fastcore>=2.2.29
@@ -124,6 +124,8 @@ Pass `lnhashs=True` to `rg` or `rg_iter` to display hash addresses instead of li
124
124
 
125
125
  For other result forms, use `rg(..., paths=True)` to return unique matched paths or `rg(..., count=True)` to count match spans. `paths` and `count` cannot both be set.
126
126
 
127
+ `^` and `$` match at the start and end of each line. A line ends at `\n` or `\r\n`. `$` also matches before a `\r` that has no `\n` after it. `rg`, `rgstr`, and `nbrg` without `multiline=True` raise `ValueError` for a pattern that contains a literal `\n` or `\r`.
128
+
127
129
  ### Path results
128
130
 
129
131
  `fd`, `walk`, and `ls` return `PathResults`, a list of absolute `Path` objects. So do `rg` and `nbrg` with `paths=True`, and their async equivalents. Indexing or iterating returns ordinary Paths:
@@ -103,6 +103,8 @@ Pass `lnhashs=True` to `rg` or `rg_iter` to display hash addresses instead of li
103
103
 
104
104
  For other result forms, use `rg(..., paths=True)` to return unique matched paths or `rg(..., count=True)` to count match spans. `paths` and `count` cannot both be set.
105
105
 
106
+ `^` and `$` match at the start and end of each line. A line ends at `\n` or `\r\n`. `$` also matches before a `\r` that has no `\n` after it. `rg`, `rgstr`, and `nbrg` without `multiline=True` raise `ValueError` for a pattern that contains a literal `\n` or `\r`.
107
+
106
108
  ### Path results
107
109
 
108
110
  `fd`, `walk`, and `ls` return `PathResults`, a list of absolute `Path` objects. So do `rg` and `nbrg` with `paths=True`, and their async equivalents. Indexing or iterating returns ordinary Paths:
@@ -6,8 +6,8 @@ For orientation, start with `rg(summary=True)`; use line-level results where nee
6
6
 
7
7
  ## Search units
8
8
 
9
- - `rg`: lines, or `SearchBlock` rows with `summary=True`. Blank/whitespace-only lines separate blocks; multiple matches in one block yield one row. Context counts the selected unit. Summary mode cannot combine with `paths` or `count`, but supports hashed block boundaries.
10
- - `nbrg`: `NbResults` of `NbCell` rows from source only, never metadata/outputs. `multiline=True` matches across cell lines while `^`/`$` remain line anchors; ordinary line-oriented `rg` rejects newline patterns.
9
+ - `rg`: lines, or `SearchBlock` rows with `summary=True`. Blank/whitespace-only lines separate blocks; multiple matches in one block yield one row. Context counts the selected unit. Summary mode cannot combine with `paths` or `count`, but supports hashed block boundaries. `^`/`$` anchor each line. A line ends at LF or CRLF.
10
+ - `nbrg`: `NbResults` of `NbCell` rows from source only, never metadata/outputs. `multiline=True` matches across cell lines while `^`/`$` remain line anchors; ordinary line-oriented `rg` rejects patterns containing a newline or carriage return.
11
11
  - Traversal/search run in parallel in Rust; sort when stable order is required. `path_re`/`skip_path_re` filter paths without pruning; `skip_dir`/`skip_dir_re` prune subtrees.
12
12
 
13
13
  ## Result fields and display
@@ -5,7 +5,7 @@ use std::sync::{
5
5
  mpsc::SyncSender,
6
6
  };
7
7
 
8
- use grep_matcher::Matcher;
8
+ use grep_matcher::{LineTerminator, Matcher};
9
9
  use grep_regex::{RegexMatcher, RegexMatcherBuilder};
10
10
  use grep_searcher::{BinaryDetection, SearcherBuilder, Sink, SinkContext, SinkContextKind, SinkError, SinkMatch};
11
11
  use ignore::{DirEntry, WalkState};
@@ -167,8 +167,8 @@ fn send_search_error(tx: &SyncSender<Result<SearchLine, RgApiError>>, err: RgApi
167
167
  pub fn compile_regex(pattern: &str, case_sensitive: Option<bool>, smart_case: bool, multiline: bool) -> Result<RegexMatcher, RgApiError> {
168
168
  if pattern.is_empty() { return Err(RgApiError::new("pattern may not be empty")); }
169
169
  let mut builder = RegexMatcherBuilder::new();
170
- if multiline { builder.multi_line(true); }
171
- else { builder.line_terminator(Some(b'\n')); }
170
+ builder.multi_line(true).crlf(true);
171
+ if multiline { builder.line_terminator(None); }
172
172
  match case_sensitive {
173
173
  Some(true) => {
174
174
  builder.case_insensitive(false);
@@ -208,7 +208,7 @@ fn search_path_cancelable(
208
208
  cancel: Option<Arc<AtomicBool>>,
209
209
  ) -> Result<Vec<SearchLine>, RgApiError> {
210
210
  let mut builder = SearcherBuilder::new();
211
- builder.line_number(true).before_context(before_context).after_context(after_context).binary_detection(BinaryDetection::quit(0));
211
+ builder.line_number(true).line_terminator(LineTerminator::crlf()).before_context(before_context).after_context(after_context).binary_detection(BinaryDetection::quit(0));
212
212
  let mut searcher = builder.build();
213
213
  let mut out = Vec::new();
214
214
  let search_matcher = matcher.clone();
@@ -236,7 +236,7 @@ fn search_bytes(
236
236
  multiline: bool,
237
237
  ) -> Result<Vec<SearchLine>, RgApiError> {
238
238
  let mut builder = SearcherBuilder::new();
239
- builder.line_number(true).before_context(before_context).after_context(after_context).multi_line(multiline);
239
+ builder.line_number(true).line_terminator(LineTerminator::crlf()).before_context(before_context).after_context(after_context).multi_line(multiline);
240
240
  let mut searcher = builder.build();
241
241
  let mut out = Vec::new();
242
242
  let search_matcher = matcher.clone();
@@ -188,8 +188,7 @@ def test_depth_size_and_filesystem_options(tmp_path):
188
188
  def test_lnhash_matches_fastcore(tmp_path):
189
189
  from fastcore.tools import lnhash as py_hash
190
190
  make_tree(tmp_path)
191
- for row in rg(".", str(tmp_path)):
192
- assert row.lnhash == py_hash(row.line_number, row.line)
191
+ for row in rg(".", str(tmp_path)): assert row.lnhash == py_hash(row.line_number, row.line)
193
192
 
194
193
 
195
194
  def test_rg_returns_structured_matches_context_and_relative_paths(tmp_path):
@@ -662,3 +661,13 @@ def test_nbrg_multiline(tmp_path):
662
661
  m, = res[0].matches
663
662
  assert m.line_number == 1 and "export" in m.line and "import" in m.line
664
663
  assert nbrg(r"^import", str(tmp_path), multiline=True, count=True) == 2 # ^ still means line start
664
+
665
+
666
+ def test_line_anchor_spans(tmp_path):
667
+ "`$` anchors at line end in match spans, for LF and CRLF lines. `count=True` sums those spans."
668
+ (tmp_path/"a.txt").write_text("foo\nbar foo\nfoo bar\nlast foo")
669
+ assert sorted((r.line_number, r.matches) for r in rg(r"foo$", tmp_path)) == [(1, [(0, 3)]), (2, [(4, 7)]), (4, [(5, 8)])]
670
+ assert rg(r"foo$", tmp_path, count=True) == 3
671
+ assert [r.matches for r in rgstr(r"foo$", "foo\nbar foo")] == [[(0, 3)], [(4, 7)]]
672
+ (tmp_path/"crlf.txt").write_bytes(b"foo\r\nbar foo\r\n")
673
+ assert sorted((r.line_number, r.line, r.matches) for r in rg(r"foo$", tmp_path/"crlf.txt")) == [(1, "foo", [(0, 3)]), (2, "bar foo", [(4, 7)])]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes