aboutsummaryrefslogtreecommitdiff
path: root/plugins/search_ui.lua
diff options
context:
space:
mode:
authorjgmdev <jgmdev@gmail.com>2023-05-24 10:45:15 -0400
committerjgmdev <jgmdev@gmail.com>2023-05-24 10:45:15 -0400
commitfac547b1d8cd3a3c6e418957fa8337c50dca5a2f (patch)
treec9889069e99325c89b5abace18a783eac1aeb16f /plugins/search_ui.lua
parent5595e2234ae22ba1426089ef22e0018a2a65000e (diff)
downloadpragtical-plugins-fac547b1d8cd3a3c6e418957fa8337c50dca5a2f.tar.gz
pragtical-plugins-fac547b1d8cd3a3c6e418957fa8337c50dca5a2f.zip
Removed search_ui, now part of pragtical
Diffstat (limited to 'plugins/search_ui.lua')
-rw-r--r--plugins/search_ui.lua979
1 files changed, 0 insertions, 979 deletions
diff --git a/plugins/search_ui.lua b/plugins/search_ui.lua
deleted file mode 100644
index 9aeedcc..0000000
--- a/plugins/search_ui.lua
+++ /dev/null
@@ -1,979 +0,0 @@
--- mod-version:3
---
--- Replacement for the find/replace and project search CommandView
----interface using Widgets with some extra features.
--- @copyright Jefferson Gonzalez <jgmdev@gmail.com>
--- @license MIT
---
-local core = require "core"
-local config = require "core.config"
-local common = require "core.common"
-local command = require "core.command"
-local keymap = require "core.keymap"
-local search = require "core.doc.search"
-local projectsearch = require "plugins.projectsearch"
-local CommandView = require "core.commandview"
-local DocView = require "core.docview"
-local Widget = require "widget"
-local Button = require "widget.button"
-local CheckBox = require "widget.checkbox"
-local Line = require "widget.line"
-local Label = require "widget.label"
-local TextBox = require "widget.textbox"
-local SelectBox = require "widget.selectbox"
-local FilePicker = require "widget.filepicker"
-
----@class config.plugins.search_ui
----@field replace_core_find boolean
----@field position "right" | "bottom"
-config.plugins.search_ui = common.merge({
- replace_core_find = true,
- position = "bottom",
- config_spec = {
- name = "Search User Interface",
- {
- label = "Replace Core Find",
- description = "Replaces the core find view when using the find shortcut.",
- path = "replace_core_find",
- type = "toggle",
- default = true
- },
- {
- label = "Position",
- description = "Location of search interface.",
- path = "position",
- type = "selection",
- default = "bottom",
- values = {
- { "Top", "top" },
- { "Right", "right" },
- { "Bottom", "bottom" }
- }
- }
- }
-}, config.plugins.search_ui)
-
----@type core.docview
-local doc_view = nil
-
----@type widget
-local widget = Widget(nil, false)
-widget.name = "Search and Replace"
-widget:set_border_width(0)
-widget.scrollable = true
-widget:hide()
-widget.init_size = true
-
----@type widget.label
-local label = Label(widget, "Find and Replace")
-label:set_position(10, 10)
-
----@type widget.line
-local line = Line(widget)
-line:set_position(0, label:get_bottom() + 10)
-
----@type widget.textbox
-local findtext = TextBox(widget, "", "search...")
-findtext:set_position(10, line:get_bottom() + 10)
-findtext:set_tooltip("Text to search")
-
----@type widget.textbox
-local replacetext = TextBox(widget, "", "replacement...")
-replacetext:set_position(10, findtext:get_bottom() + 10)
-replacetext:set_tooltip("Text to replace")
-
----@type widget.button
-local findprev = Button(widget, "")
-findprev:set_icon("<")
-findprev:set_position(10, replacetext:get_bottom() + 10)
-findprev:set_tooltip("Find previous")
-
----@type widget.button
-local findnext = Button(widget, "")
-findnext:set_icon(">")
-findnext:set_position(findprev:get_right() + 5, replacetext:get_bottom() + 10)
-findnext:set_tooltip("Find next")
-
----@type widget.button
-local findproject = Button(widget, "Find")
-findproject:set_icon("L")
-findproject:set_position(findprev:get_right() + 5, replacetext:get_bottom() + 10)
-findproject:set_tooltip("Find in project")
-findproject:hide()
-
----@type widget.button
-local replace = Button(widget, "Replace")
-replace:set_position(10, findnext:get_bottom() + 10)
-replace:set_tooltip("Replace all matching results")
-
----@type widget.line
-local line_options = Line(widget)
-line_options:set_position(0, replace:get_bottom() + 10)
-
----@type widget.checkbox
-local insensitive = CheckBox(widget, "Insensitive")
-insensitive:set_position(10, line_options:get_bottom() + 10)
-insensitive:set_tooltip("Case insensitive search")
-insensitive:set_checked(true)
-
----@type widget.checkbox
-local patterncheck = CheckBox(widget, "Pattern")
-patterncheck:set_position(10, insensitive:get_bottom() + 10)
-patterncheck:set_tooltip("Treat search text as a lua pattern")
-
----@type widget.checkbox
-local regexcheck = CheckBox(widget, "Regex")
-regexcheck:set_position(10, patterncheck:get_bottom() + 10)
-regexcheck:set_tooltip("Treat search text as a regular expression")
-
----@type widget.checkbox
-local replaceinselection = CheckBox(widget, "Replace in Selection")
-replaceinselection:set_position(10, regexcheck:get_bottom() + 10)
-replaceinselection:set_tooltip("Perform replace only on selected text")
-
----@type widget.selectbox
-local scope = SelectBox(widget, "scope")
-scope:set_position(10, regexcheck:get_bottom() + 10)
-scope:add_option("current file")
-scope:add_option("project files")
-scope:set_selected(1)
-
----@type widget.filepicker
-local filepicker = FilePicker(widget)
-filepicker:set_mode(FilePicker.mode.DIRECTORY)
-filepicker:set_position(10, scope:get_bottom() + 10)
-filepicker:set_tooltip("Directory to perform the search")
-filepicker:hide()
-
----@type widget.line
-local statusline = Line(widget)
-statusline:set_position(0, scope:get_bottom() + 10)
-
----@type widget.label
-local status = Label(widget, "")
-status:set_position(10, statusline:get_bottom() + 10)
-
---------------------------------------------------------------------------------
--- Helper class to keep track of amount of matches and display on status label
---------------------------------------------------------------------------------
----@class plugins.search_ui.result
----@field line integer
----@field col integer
-
----@class plugins.search_ui.results
----@field text string
----@field matches plugins.search_ui.result[]
----@field doc core.doc?
-local Results = {
- text = "",
- matches = {},
- doc = nil,
- prev_search_id = 0
-}
-
----@param text string
----@param doc core.doc
-function Results:find(text, doc, force)
- if self.text == text and self.doc == doc and not force then
- self:set_status()
- return
- end
-
- -- disable previous search thread
- if self.prev_search_id > 0 and core.threads[self.prev_search_id] then
- core.threads[self.prev_search_id] = {
- cr = coroutine.create(function() end), wake = 0
- }
- end
-
- self.text = text
- self.doc = doc
-
- local search_func
-
- -- regex search
- if regexcheck:is_checked() then
- local regex_find_offsets = regex.match
- if regex.find_offsets then
- regex_find_offsets = regex.find_offsets
- end
- local pattern = regex.compile(
- findtext:get_text(),
- insensitive:is_checked() and "im" or "m"
- )
- if not pattern then return end
- search_func = function(line_text)
- ---@cast line_text string
- local results = nil
- local offsets = {regex_find_offsets(pattern, line_text)}
- if offsets[1] then
- results = {}
- for i=1, #offsets, 2 do
- table.insert(results, offsets[i])
- end
- end
- return results
- end
- -- plain or pattern search
- else
- local no_case = insensitive:is_checked()
- local is_plain = not patterncheck:is_checked()
- if is_plain and no_case then
- text = text:ulower()
- end
- search_func = function(line_text)
- ---@cast line_text string
- if is_plain and no_case then
- line_text = line_text:ulower()
- end
- local results = nil
- local col1, col2 = line_text:find(text, 1, is_plain)
- if col1 then
- results = {}
- table.insert(results, col1)
- while col1 do
- col1, col2 = line_text:find(text, col2+1, is_plain)
- if col1 then
- table.insert(results, col1)
- end
- end
- end
- return results
- end
- end
-
- self.prev_search_id = core.add_thread(function()
- self.matches = {}
- local lines_count = #doc.lines
- for i=1, lines_count do
- local offsets = search_func(doc.lines[i])
- if offsets then
- for _, col in ipairs(offsets) do
- table.insert(self.matches, {line = i, col = col})
- end
- end
- if i % 100 == 0 then
- coroutine.yield()
- end
- end
- self:set_status()
- end)
-end
-
----@return integer
-function Results:current()
- if not self.doc then return 0 end
- local line1, col1, line2, col2 = self.doc:get_selection()
- if line1 == line2 and col1 == col2 then return 0 end
- local line = math.min(line1, line2)
- local col = math.min(col1, col2)
- if self.matches and #self.matches > 0 then
- for i, result in ipairs(self.matches) do
- if result.line == line and result.col == col then
- return i
- end
- end
- end
- return 0
-end
-
-function Results:clear()
- self.text = ""
- self.matches = {}
- self.doc = nil
- status:set_label("")
-end
-
-function Results:set_status()
- local current = self:current()
- local total = self.matches and #self.matches or 0
- if total > 0 then
- status:set_label(
- "Result: " .. tostring(current .. " of " .. tostring(total))
- )
- else
- status:set_label("")
- end
-end
-
---------------------------------------------------------------------------------
--- Helper functions
---------------------------------------------------------------------------------
-local function view_is_open(target_view)
- if not target_view then return false end
- local found = false
- for _, view in ipairs(core.root_view.root_node:get_children()) do
- if view == target_view then
- found = true
- break
- end
- end
- return found
-end
-
-local function toggle_scope(idx, not_set)
- if not not_set then scope:set_selected(idx) end
-
- if idx == 1 then
- replacetext:show()
- findnext:show()
- findprev:show()
- replace:show()
- patterncheck:show()
- replaceinselection:show()
- findproject:hide()
- filepicker:hide()
-
- if view_is_open(doc_view) and findtext:get_text() ~= "" then
- Results:find(findtext:get_text(), doc_view.doc)
- else
- Results:clear()
- end
- else
- replacetext:hide()
- findnext:hide()
- findprev:hide()
- replace:hide()
- patterncheck:hide()
- replaceinselection:hide()
- findproject:show()
- filepicker:show()
-
- Results:clear()
- end
-end
-
-local function project_search()
- if findtext:get_text() == "" then return end
- if not regexcheck:is_checked() then
- projectsearch.search_plain(
- findtext:get_text(), filepicker:get_path(), insensitive:is_checked()
- )
- else
- projectsearch.search_regex(
- findtext:get_text(), filepicker:get_path(), insensitive:is_checked()
- )
- end
- command.perform "search-replace:hide"
-end
-
-local find_enabled = true
-local function find(reverse)
- if
- not view_is_open(doc_view) or findtext:get_text() == "" or not find_enabled
- then
- Results:clear()
- return
- end
-
- if core.last_active_view and core.last_active_view:is(DocView) then
- doc_view = core.last_active_view
- end
-
- local doc = doc_view.doc
- local cline1, ccol1, cline2, ccol2 = doc:get_selection()
- local line, col = cline1, ccol1
- if reverse and ccol2 < ccol1 then
- col = ccol2
- end
-
- local opt = {
- wrap = true,
- no_case = insensitive:is_checked(),
- pattern = patterncheck:is_checked(),
- regex = regexcheck:is_checked(),
- reverse = reverse
- }
-
- if opt.regex and not regex.compile(findtext:get_text()) then
- return
- end
-
- status:set_label("")
-
- core.try(function()
- local line1, col1, line2, col2 = search.find(
- doc, line, col, findtext:get_text(), opt
- )
-
- local current_text = doc:get_text(
- table.unpack({ doc:get_selection() })
- )
-
- if opt.no_case and not opt.regex and not opt.pattern then
- current_text = current_text:ulower()
- end
-
- if line1 then
- local text = findtext:get_text()
- if opt.no_case and not opt.regex and not opt.pattern then
- text = text:ulower()
- end
- if reverse or (current_text == text or current_text == "") then
- doc:set_selection(line1, col2, line2, col1)
- else
- doc:set_selection(line1, col1, line2, col2)
- end
- doc_view:scroll_to_line(line1, true)
- Results:find(text, doc)
- end
- end)
-end
-
-local function find_replace()
- if core.last_active_view:is(DocView) then
- doc_view = core.last_active_view
- end
- local doc = doc_view.doc
-
- if not replaceinselection:is_checked() then
- local line1, col1, line2, col2 = doc:get_selection()
- if line1 ~= line2 or col1 ~= col2 then
- doc:set_selection(line1, col1)
- end
- end
-
- local old = findtext:get_text()
- local new = replacetext:get_text()
-
- local results = doc:replace(function(text)
- if not regexcheck:is_checked() then
- if not patterncheck:is_checked() then
- return text:gsub(old:gsub("%W", "%%%1"), new:gsub("%%", "%%%%"), nil)
- else
- return text:gsub(old, new)
- end
- end
- local result, matches = regex.gsub(regex.compile(old, "m"), text, new)
- if type(matches) == "table" then
- return result, #matches
- end
- return result, matches
- end)
-
- local n = 0
- for _,v in pairs(results) do
- n = n + v
- end
-
- status:set_label(string.format("Total Replaced: %d", n))
-end
-
-local inside_node = false
-local current_node = nil
-local current_position = ""
-
-local function add_to_node()
- if not inside_node or current_position ~= config.plugins.search_ui.position then
- if
- current_position ~= ""
- and
- current_position ~= config.plugins.search_ui.position
- then
- widget:hide()
- current_node:remove_view(core.root_view.root_node, widget)
- core.root_view.root_node:update_layout()
- widget:set_size(0, 0)
- widget.init_size = true
- end
- local node = core.root_view:get_primary_node()
- if config.plugins.search_ui.position == "right" then
- current_node = node:split("right", widget, {x=true}, true)
- current_position = "right"
- elseif config.plugins.search_ui.position == "top" then
- current_node = node:split("up", widget, {y=true}, false)
- current_position = "top"
- else
- current_node = node:split("down", widget, {y=true}, false)
- current_position = "bottom"
- end
- widget:show()
- inside_node = true
- end
-end
-
----Show or hide the search pane.
----@param av? core.docview
----@param toggle? boolean
-local function show_find(av, toggle)
- if
- not view_is_open(av)
- and
- scope:get_selected() == 1
- then
- widget:swap_active_child()
- if config.plugins.search_ui.position == "right" then
- widget:hide_animated(false, true)
- else
- widget:hide_animated(true, false)
- end
- return
- end
-
- if inside_node and current_position == config.plugins.search_ui.position then
- if toggle then
- widget:toggle_visible(true, false, true)
- else
- if not widget:is_visible() then
- if config.plugins.search_ui.position == "right" then
- widget:show_animated(false, true)
- else
- widget:show_animated(true, false)
- end
- end
- end
- else
- add_to_node()
- end
-
- if widget:is_visible() then
- status:set_label("")
-
- widget:swap_active_child(findtext)
- doc_view = av
- if view_is_open(doc_view) and doc_view.doc then
- local doc_text = doc_view.doc:get_text(
- table.unpack({ doc_view.doc:get_selection() })
- )
- if insensitive:is_checked() then doc_text = doc_text:ulower() end
- local current_text = findtext:get_text()
- if insensitive:is_checked() then current_text = current_text:ulower() end
- if doc_text and doc_text ~= "" and current_text ~= doc_text then
- local original_text = doc_view.doc:get_text(
- table.unpack({ doc_view.doc:get_selection() })
- )
- find_enabled = false
- findtext:set_text(original_text)
- find_enabled = true
- elseif current_text ~= "" and doc_text == "" then
- if scope:get_selected() == 1 then
- find(false)
- end
- end
- if findtext:get_text() ~= "" then
- findtext.textview.doc:set_selection(1, math.huge, 1, 1)
- if scope:get_selected() == 1 then
- Results:find(findtext:get_text(), doc_view.doc)
- else
- Results:clear()
- end
- else
- Results:clear()
- end
- end
- else
- widget:swap_active_child()
- if view_is_open(doc_view) then
- core.set_active_view(doc_view)
- end
- end
-end
-
---------------------------------------------------------------------------------
--- Widgets event overrides
---------------------------------------------------------------------------------
-function findtext:on_change(text)
- if scope:get_selected() == 1 then
- find(false)
- end
-end
-
-function insensitive:on_checked(checked)
- Results:clear()
-end
-
-function patterncheck:on_checked(checked)
- if checked then
- regexcheck:set_checked(false)
- end
- Results:clear()
-end
-
-function regexcheck:on_checked(checked)
- if checked then
- patterncheck:set_checked(false)
- end
- Results:clear()
-end
-
-function scope:on_selected(idx)
- toggle_scope(idx, true)
- if not view_is_open(doc_view) and idx == 1 then
- command.perform "search-replace:hide"
- end
-end
-
-function findnext:on_click() find(false) end
-function findprev:on_click() find(true) end
-function findproject:on_click() project_search() end
-function replace:on_click() find_replace() end
-
----@param self widget
-local function update_size(self)
- if config.plugins.search_ui.position == "right" then
- if scope:get_selected() == 1 then
- if self.size.x < replace:get_right() + replace:get_width() / 2 then
- self.size.x = replace:get_right() + replace:get_width() / 2
- end
- else
- if self.size.x < findproject:get_right() + findproject:get_width() * 2 then
- self.size.x = findproject:get_right() + findproject:get_width() * 2
- end
- end
- else
- self:set_size(nil, self:get_real_height() + 10)
- end
-end
-
----@param self widget
-local function update_right_positioning(self)
- scope:show()
- label:show()
- status:show()
- line_options:show()
- label:set_label("Find and Replace")
-
- label:set_position(10, 10)
- line:set_position(0, label:get_bottom() + 10)
- findtext:set_position(10, line:get_bottom() + 10)
- findtext.size.x = self.size.x - 20
-
- if scope:get_selected() == 1 then
- replacetext:set_position(10, findtext:get_bottom() + 10)
- replacetext.size.x = self.size.x - 20
- findprev:set_position(10, replacetext:get_bottom() + 10)
- findnext:set_position(findprev:get_right() + 5, replacetext:get_bottom() + 10)
- replace:set_position(findnext:get_right() + 5, replacetext:get_bottom() + 10)
- line_options:set_position(0, replace:get_bottom() + 10)
- else
- findproject:set_position(10, findtext:get_bottom() + 10)
- replace:set_position(findproject:get_right() + 5, replacetext:get_bottom() + 10)
- line_options:set_position(0, findproject:get_bottom() + 10)
- end
-
- insensitive:set_position(10, line_options:get_bottom() + 10)
- if scope:get_selected() == 1 then
- patterncheck:set_position(10, insensitive:get_bottom() + 10)
- regexcheck:set_position(10, patterncheck:get_bottom() + 10)
- replaceinselection:set_position(10, regexcheck:get_bottom() + 10)
- scope:set_position(10, replaceinselection:get_bottom() + 10)
- else
- regexcheck:set_position(10, insensitive:get_bottom() + 10)
- scope:set_position(10, regexcheck:get_bottom() + 10)
- end
-
- scope:set_size(self.size.x - 20)
- if scope:get_selected() == 1 then
- statusline:set_position(0, scope:get_bottom() + 30)
- else
- filepicker:set_position(10, scope:get_bottom() + 10)
- filepicker:set_size(self.size.x - 20, nil)
- statusline:set_position(0, filepicker:get_bottom() + 30)
- end
-
- status:set_position(10, statusline:get_bottom() + 10)
- if status.label == "" then
- statusline:hide()
- else
- statusline:show()
- end
-
- if self.init_size then
- update_size(self)
- self.init_size = false
- self:show_animated(false, true)
- end
-
- add_to_node()
-end
-
----@param self widget
-local function update_bottom_positioning(self)
- scope:hide()
- statusline:hide()
-
- if scope:get_selected() == 1 then
- label:hide()
- status:show()
- status:set_position(10, 10)
- replaceinselection:set_position(self.size.x - replaceinselection:get_width() - 10, 10)
- regexcheck:set_position(replaceinselection:get_position().x - 10 - regexcheck:get_width(), 10)
- patterncheck:set_position(regexcheck:get_position().x - 10 - patterncheck:get_width(), 10)
- insensitive:set_position(patterncheck:get_position().x - 10 - insensitive:get_width(), 10)
- line:set_position(0, status:get_bottom() + 10)
- else
- label:show()
- status:hide()
- label:set_label("Find in Directory")
- label:set_position(10, 10)
- regexcheck:set_position(self.size.x - regexcheck:get_width() - 10, 10)
- insensitive:set_position(regexcheck:get_position().x - 10 - insensitive:get_width(), 10)
- line:set_position(0, label:get_bottom() + 10)
- end
-
- if scope:get_selected() == 1 then
- findtext:set_position(10, line:get_bottom() + 10)
- findtext.size.x = self.size.x - 40 - findprev:get_width() - findnext:get_width()
- findnext:set_position(self.size.x - 10 - findnext:get_width(), line:get_bottom() + 10)
- findprev:set_position(findnext:get_position().x - 10 - findprev:get_width(), line:get_bottom() + 10)
- replacetext:set_position(10, findtext:get_bottom() + 10)
- replacetext.size.x = findtext.size.x
- replace:set_position(self.size.x - 15 - replace:get_width(), findtext:get_bottom() + 10)
- replace.size.x = findprev:get_width() + findnext:get_width() + 10
- line_options:hide()
- else
- findtext:set_position(10, line:get_bottom() + 10)
- findtext.size.x = self.size.x - 30 - findproject:get_width()
- findproject:set_position(self.size.x - 10 - findproject:get_width(), line:get_bottom() + 10)
- replace:set_position(findproject:get_right() + 5, replacetext:get_bottom() + 10)
- line_options:show()
- line_options:set_position(0, findproject:get_bottom() + 10)
- filepicker:set_position(10, line_options:get_bottom() + 10)
- filepicker:set_size(self.size.x - 20, nil)
- end
-
- if self.init_size then
- update_size(self)
- self.init_size = false
- self:show_animated(true, false)
- end
-
- add_to_node()
-end
-
--- reposition items on scale changes
-function widget:update()
- if Widget.update(self) then
- if config.plugins.search_ui.position == "right" then
- update_right_positioning(self)
- else
- update_bottom_positioning(self)
- end
- end
-end
-
-function widget:on_scale_change(...)
- Widget.on_scale_change(self, ...)
- update_size(self)
-end
-
---------------------------------------------------------------------------------
--- Override set_active_view to keep track of currently active docview
---------------------------------------------------------------------------------
-local core_set_active_view = core.set_active_view
-function core.set_active_view(...)
- core_set_active_view(...)
- local view = core.next_active_view or core.active_view
- if
- view ~= doc_view
- and
- widget:is_visible()
- and
- view:extends(DocView)
- and
- view ~= findtext.textview
- and
- view ~= replacetext.textview
- and
- view.doc.filename
- then
- doc_view = view
- Results:clear()
- end
-end
-
---------------------------------------------------------------------------------
--- Register commands
---------------------------------------------------------------------------------
-command.add(
- function()
- if core.active_view:is(DocView) then
- return true, core.active_view
- elseif widget:is_visible() then
- return true, doc_view
- elseif scope:get_selected() == 2 then
- return true, nil
- end
- return false
- end,
- {
- ["search-replace:show"] = function(av)
- show_find(av, false)
- end,
-
- ["search-replace:toggle"] = function(av)
- show_find(av, true)
- end
- }
-)
-
-command.add(function() return widget:is_visible() and not core.active_view:is(CommandView) end, {
- ["search-replace:hide"] = function()
- widget:swap_active_child()
- if config.plugins.search_ui.position == "right" then
- widget:hide_animated(false, true)
- else
- widget:hide_animated(true, false)
- end
- if view_is_open(doc_view) then
- core.set_active_view(doc_view)
- end
- end,
-
- ["search-replace:file-search"] = function()
- toggle_scope(1)
- command.perform "search-replace:show"
- end,
-
- ["search-replace:next"] = function()
- find(false)
- end,
-
- ["search-replace:previous"] = function()
- find(true)
- end,
-
- ["search-replace:toggle-sensitivity"] = function()
- insensitive:set_checked(not insensitive:is_checked())
- Results:clear()
- end,
-
- ["search-replace:toggle-regex"] = function()
- regexcheck:set_checked(not regexcheck:is_checked())
- Results:clear()
- end,
-
- ["search-replace:toggle-in-selection"] = function()
- replaceinselection:set_checked(not replaceinselection:is_checked())
- end
-})
-
-command.add(
- function()
- return widget:is_visible()
- and
- not core.active_view:is(CommandView)
- and
- (
- widget.child_active == findtext
- or
- widget.child_active == replacetext
- )
- end,
- {
- ["search-replace:perform"] = function()
- if scope:get_selected() == 1 then
- if widget.child_active == findtext then
- ---@type core.doc
- local doc = doc_view.doc
- local line1, col1, line2, col2 = doc:get_selection()
- -- correct cursor position to properly search next result
- if line1 ~= line2 or col1 ~= col2 then
- doc:set_selection(
- line1,
- math.max(col1, col2),
- line2,
- math.min(col1, col2)
- )
- end
- find(false)
- else
- find_replace()
- end
- else
- project_search()
- end
- end
- }
-)
-
---------------------------------------------------------------------------------
--- Override core find/replace commands
---------------------------------------------------------------------------------
-local find_replace_find = command.map["find-replace:find"].perform
-command.map["find-replace:find"].perform = function(...)
- if config.plugins.search_ui.replace_core_find then
- toggle_scope(1)
- command.perform "search-replace:show"
- else
- find_replace_find(...)
- end
-end
-
-local find_replace_replace = command.map["find-replace:replace"].perform
-command.map["find-replace:replace"].perform = function(...)
- if config.plugins.search_ui.replace_core_find then
- toggle_scope(1)
- command.perform "search-replace:show"
- else
- find_replace_replace(...)
- end
-end
-
-local find_replace_repeat = command.map["find-replace:repeat-find"].perform
-command.map["find-replace:repeat-find"].perform = function(...)
- if
- widget:is_visible()
- or
- (config.plugins.search_ui.replace_core_find and findtext:get_text() ~= "")
- then
- find(false)
- return
- end
- find_replace_repeat(...)
-end
-
-local find_replace_previous = command.map["find-replace:previous-find"].perform
-command.map["find-replace:previous-find"].perform = function(...)
- if
- widget:is_visible()
- or
- (config.plugins.search_ui.replace_core_find and findtext:get_text() ~= "")
- then
- find(true)
- return
- end
- find_replace_previous(...)
-end
-
-local project_search_find = command.map["project-search:find"].perform
-command.map["project-search:find"].perform = function(path)
- if config.plugins.search_ui.replace_core_find then
- toggle_scope(2)
- if path then
- filepicker:set_path(path)
- end
- local av = doc_view
- if
- core.active_view:extends(DocView)
- and
- core.active_view ~= findtext.textview
- and
- core.active_view ~= replacetext.textview
- then
- av = core.active_view
- end
- show_find(av, false)
- return
- end
- project_search_find(path)
-end
-
---------------------------------------------------------------------------------
--- Register keymaps
---------------------------------------------------------------------------------
-keymap.add {
- ["alt+h"] = "search-replace:toggle",
- ["escape"] = "search-replace:hide",
- ["f3"] = "search-replace:next",
- ["shift+f3"] = "search-replace:previous",
- ["return"] = "search-replace:perform",
- ["shift+return"] = "search-replace:previous",
- ["ctrl+i"] = "search-replace:toggle-sensitivity",
- ["ctrl+shift+i"] = "search-replace:toggle-regex",
- ["ctrl+alt+i"] = "search-replace:toggle-in-selection",
- ["ctrl+f"] = "search-replace:file-search"
-}
-
-
-return widget