Skip to content

Commit

Permalink
feat: case-insensitive search
Browse files Browse the repository at this point in the history
API: new `opts` field `ignore_case`.

Closes #64
  • Loading branch information
ggandor committed Dec 19, 2021
1 parent 42a44ad commit b6ccf82
Show file tree
Hide file tree
Showing 4 changed files with 430 additions and 384 deletions.
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ defaults.)

```Lua
require'lightspeed'.setup {
ignore_case = false,
exit_after_idle_msecs = { labeled = nil, unlabeled = 1000 },

-- s/x
Expand Down Expand Up @@ -616,14 +617,12 @@ nnoremap <expr> g/ '/<C-u>\%>'.(col(".")-v:count1).'v\%<'.(col(".")+v:count1).'v
nnoremap <expr> g? '?<C-u>\%>'.(col(".")-v:count1).'v\%<'.(col(".")+v:count1).'v'
```

### Case insensitivity for 2-character search?
### Smart case?

See [#64](https://github.com/ggandor/lightspeed.nvim/issues/64). TL;DR:
`smartcase`-like behaviour would be super-useful, but is unfortunately
impossible for this plugin, _by design_. At the same time, the value of a plain
"ignore case" setting is questionable, because that would mean ignoring our
clever "shortcutting" features too. Here, capitals can very frequently make you
reach the target faster - so start using them!
See [#64](https://github.com/ggandor/lightspeed.nvim/issues/64). It is
unfortunately impossible for this plugin, _by design_. (Because of ahead-of-time
labeling, it would require showing two different labels - corresponding to two
different futures - at the same time.)

### Arbitrary-length search pattern?

Expand Down
6 changes: 5 additions & 1 deletion doc/lightspeed.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*lightspeed.txt* For Neovim version 0.5.0 Last change: 2021 December 13
*lightspeed.txt* For Neovim version 0.5.0 Last change: 2021 December 19

.-.. .. --. .... - ... .--. . . -..
__ _ __ __ __
Expand Down Expand Up @@ -154,6 +154,10 @@ Setting multiple options via the `setup` function: >

Common options~

`ignore_case = false`

Ignore case in search patterns.

`exit_after_idle_msecs = { labeled = nil, unlabeled = 1000 }`

Timeout value, in milliseconds, after which the plugin should exit
Expand Down
44 changes: 28 additions & 16 deletions fnl/lightspeed.fnl
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ character instead."
"u" "t"
"m" "v" "c" "a" "." "z"
"/" "F" "L" "N" "H" "G" "M" "U" "T" "?" "Z"])
{:exit_after_idle_msecs {:labeled nil
:unlabeled 1000}
{:ignore_case false
:exit_after_idle_msecs {:labeled nil :unlabeled 1000}
; s/x
:grey_out_search_area true
:highlight_unique_chars true
Expand Down Expand Up @@ -755,7 +755,9 @@ interrupted change-operation."
(var jump-pos nil)
(var match-count 0)
(let [next-pos (vim.fn.searchpos "\\_." (if reverse? :nWb :nW))
pattern (if to-eol? "\\n" (.. "\\V\\C" (in1:gsub "\\" "\\\\")))
pattern (if to-eol? "\\n"
(.. "\\V" (if opts.ignore_case "\\c" "\\C")
(in1:gsub "\\" "\\\\")))
limit (+ count (get-num-of-matches-to-be-highlighted))]
(each [[line col &as pos]
(onscreen-match-positions pattern reverse? {:ft-search? true : limit})]
Expand Down Expand Up @@ -839,7 +841,8 @@ interrupted change-operation."
(for [col startcol endcol]
(when (or vim.wo.wrap (and (>= col left-bound) (<= col right-bound)))
; TODO: multibyte?
(let [ch (line:sub col col)]
(let [ch (line:sub col col)
ch (if opts.ignore_case (ch:lower) ch)]
(tset unique-chars ch (match (. unique-chars ch)
pos-already-there false
_ [lnum col])))))))
Expand All @@ -849,9 +852,9 @@ interrupted change-operation."
(hl:add-hl hl.group.unique-ch (dec lnum) (dec col) col)))))


(fn get-targets [ch1 reverse?]
(fn get-targets [input reverse?]
"Return a table that will store the positions and other metadata of
all on-screen pairs that start with `ch1`, in the order of discovery
all on-screen pairs that start with `input`, in the order of discovery
(i.e., distance from cursor).
A target element in its final form has the following fields (the latter
Expand All @@ -866,17 +869,21 @@ ones might be set by subsequent functions):
?beacon : [col-offset [[char hl-group]]]
"
(local targets [])
(local to-eol? (= ch1 "\r"))
(local to-eol? (= input "\r"))
(var prev-match {})
(var added-prev-match? nil)
(let [pattern (if to-eol? "\\n" ; we should send in a literal \n, for searchpos
(.. "\\V\\C" ; force matching case (for the moment)
(ch1:gsub "\\" "\\\\") ; backslash still needs to be escaped for \V
"\\_."))] ; match anything (including EOL) after ch1
(let [pattern (if to-eol? "\\n" ; we should send in a literal \n, for searchpos
(.. "\\V"
(if opts.ignore_case "\\c" "\\C")
(input:gsub "\\" "\\\\") ; backslash still needs to be escaped for \V
"\\_."))] ; match anything (including EOL) after it
(each [[line col &as pos] (onscreen-match-positions pattern reverse? {: to-eol?})]
(if to-eol? (table.insert targets {:pos pos :pair ["\n" ""]})
(let [ch2 (or (char-at-pos pos {:char-offset 1})
"\r") ; <enter> is the expected input for line breaks
(let [ch1 (char-at-pos pos {}) ; not necessarily = `input` (if case-insensitive)
ch2 (or (char-at-pos pos {:char-offset 1})
; <enter> is the expected input for line breaks, so
; let's return the key for the sublist right away.
"\r")
to-pre-eol? (= ch2 "\r")
overlaps-prev-match? (and (= line prev-match.line)
(= col ((if reverse? dec inc) prev-match.col)))
Expand Down Expand Up @@ -924,10 +931,15 @@ ones might be set by subsequent functions):
easy iteration through each subset of targets with a given successor
char separately."
(tset targets :sublists {})
(when opts.ignore_case
(setmetatable targets.sublists
{:__index (fn [self k]
(rawget self (k:lower)))}))
(each [_ {:pair [_ ch2] &as target} (ipairs targets)]
(when-not (. targets :sublists ch2)
(tset targets :sublists ch2 []))
(table.insert (. targets :sublists ch2) target)))
(let [k (if opts.ignore_case (ch2:lower) ch2)]
(when-not (. targets :sublists k)
(tset targets :sublists k []))
(table.insert (. targets :sublists k) target))))


(fn get-labels [sublist to-eol?]
Expand Down
Loading

0 comments on commit b6ccf82

Please sign in to comment.