aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/ui.lua56
-rw-r--r--modules/textadept/find.lua2
-rw-r--r--test/test.lua54
3 files changed, 77 insertions, 35 deletions
diff --git a/core/ui.lua b/core/ui.lua
index ce7aeb84..7aa15070 100644
--- a/core/ui.lua
+++ b/core/ui.lua
@@ -33,16 +33,25 @@ local ui = ui
-- with a group of [`ui.print()`]() and [`ui._print()`]() function calls.
-- The default value is `false`, and focuses buffers when messages are printed
-- to them.
--- @field highlight_words (bool)
--- Whether or not to automatically highlight all instances of the selected
--- word.
--- The default value is `true` except in the terminal version.
+-- @field highlight_words (number)
+-- The word highlight mode.
+--
+-- * `ui.HIGHLIGHT_CURRENT`
+-- Automatically highlight all instances of the current word.
+-- * `ui.HIGHLIGHT_SELECTED`
+-- Automatically highlight all instances of the selected word.
+-- * `ui.HIGHLIGHT_NONE`
+-- Do not automatically highlight words.
+--
+-- The default value is `ui.HIGHLIGHT_SELECTED` except in the terminal
+-- version, where it is `ui.HIGHLIGHT_NONE`.
-- @field INDIC_HIGHLIGHT (number)
-- The word highlight indicator number.
module('ui')]]
ui.silent_print = false
-ui.highlight_words = not CURSES
+ui.HIGHLIGHT_NONE, ui.HIGHLIGHT_CURRENT, ui.HIGHLIGHT_SELECTED = 1, 2, 3
+ui.highlight_words = not CURSES and ui.HIGHLIGHT_SELECTED or ui.HIGHLIGHT_NONE
ui.INDIC_HIGHLIGHT = _SCINTILLA.next_indic_number()
-- Helper function for printing messages to buffers.
@@ -300,21 +309,30 @@ events_connect(events.KEYPRESS, function(code)
if keys.KEYSYMS[code] == 'esc' then clear_highlighted_words() end
end, 1)
--- Highlight all instances of the selected word.
+-- Highlight all instances of the current or selected word.
events_connect(events.UPDATE_UI, function(updated)
- if updated and updated & buffer.UPDATE_SELECTION > 0 and
- ui.highlight_words and not buffer.selection_empty and
- buffer:is_range_word(buffer.selection_start, buffer.selection_end) and
- buffer:get_sel_text():find('^%S+$') then
- clear_highlighted_words()
- local word = buffer:text_range(buffer.selection_start, buffer.selection_end)
- buffer.search_flags = buffer.FIND_MATCHCASE | buffer.FIND_WHOLEWORD
- buffer:target_whole_document()
- while buffer:search_in_target(word) ~= -1 do
- buffer:indicator_fill_range(
- buffer.target_start, buffer.target_end - buffer.target_start)
- buffer:set_target_range(buffer.target_end, buffer.length + 1)
- end
+ if not updated or updated & buffer.UPDATE_SELECTION == 0 then return end
+ local word
+ if ui.highlight_words == ui.HIGHLIGHT_CURRENT then
+ local s = buffer:word_start_position(buffer.current_pos, true)
+ local e = buffer:word_end_position(buffer.current_pos, true)
+ if s == e then clear_highlighted_words() return end
+ word = buffer:text_range(s, e)
+ elseif ui.highlight_words == ui.HIGHLIGHT_SELECTED then
+ local s, e = buffer.selection_start, buffer.selection_end
+ if not buffer:is_range_word(s, e) then return end
+ word = buffer:get_sel_text()
+ if not word:find('^%S+$') then return end
+ else
+ return
+ end
+ clear_highlighted_words()
+ buffer.search_flags = buffer.FIND_MATCHCASE | buffer.FIND_WHOLEWORD
+ buffer:target_whole_document()
+ while buffer:search_in_target(word) ~= -1 do
+ buffer:indicator_fill_range(
+ buffer.target_start, buffer.target_end - buffer.target_start)
+ buffer:set_target_range(buffer.target_end, buffer.length + 1)
end
end)
diff --git a/modules/textadept/find.lua b/modules/textadept/find.lua
index 7442276f..2a107b7c 100644
--- a/modules/textadept/find.lua
+++ b/modules/textadept/find.lua
@@ -127,7 +127,7 @@ local function find(text, next, flags, no_wrap, wrapped)
-- Highlight all occurrences first, otherwise regex tags will be overwritten.
buffer.indicator_current = ui.INDIC_HIGHLIGHT
buffer:indicator_clear_range(1, buffer.length)
- if ui.highlight_words and #text > 1 then
+ if ui.highlight_words ~= ui.HIGHLIGHT_NONE and #text > 1 then
buffer.search_flags = flags
buffer:target_whole_document()
while buffer:search_in_target(text) ~= -1 do
diff --git a/test/test.lua b/test/test.lua
index c3c58f92..d2be6516 100644
--- a/test/test.lua
+++ b/test/test.lua
@@ -1807,40 +1807,46 @@ function test_editing_convert_indentation()
end
function test_ui_highlight_word()
+ local function verify(indics)
+ local bit = 1 << ui.INDIC_HIGHLIGHT - 1
+ for _, pos in ipairs(indics) do
+ local mask = buffer:indicator_all_on_for(pos)
+ assert(mask & bit > 0, 'no indicator on line %d', buffer:line_from_position(pos))
+ end
+ end
+
local highlight = ui.highlight_words
- ui.highlight_words = true
+ ui.highlight_words = ui.HIGHLIGHT_SELECTED
buffer.new()
buffer:append_text(table.concat({
'foo',
'foobar',
- 'bar foo',
+ 'bar foo',
'baz foo bar',
'fooquux',
'foo'
}, '\n'))
+ local function verify_foo()
+ verify{
+ buffer:position_from_line(LINE(1)),
+ buffer:position_from_line(LINE(3)) + 5,
+ buffer:position_from_line(LINE(4)) + 4,
+ buffer:position_from_line(LINE(6))
+ }
+ end
textadept.editing.select_word()
ui.update()
- local indics = {
- buffer:position_from_line(LINE(1)),
- buffer:position_from_line(LINE(3)) + 4,
- buffer:position_from_line(LINE(4)) + 4,
- buffer:position_from_line(LINE(6))
- }
- local bit = 1 << ui.INDIC_HIGHLIGHT - 1
- for _, pos in ipairs(indics) do
- local mask = buffer:indicator_all_on_for(pos)
- assert(mask & bit > 0, 'no indicator on line %d', buffer:line_from_position(pos))
- end
+ verify_foo()
events.emit(events.KEYPRESS, not CURSES and 0xFF1B or 7) -- esc
local pos = buffer:indicator_end(ui.INDIC_HIGHLIGHT, 1)
assert_equal(pos, 1) -- highlights cleared
-- Verify turning off word highlighting.
- ui.highlight_words = false
+ ui.highlight_words = ui.HIGHLIGHT_NONE
textadept.editing.select_word()
ui.update()
pos = buffer:indicator_end(ui.INDIC_HIGHLIGHT, 2)
assert_equal(pos, 1) -- no highlights
- ui.highlight_words = true -- reset
+ ui.highlight_words = ui.HIGHLIGHT_SELECTED -- reset
-- Verify partial word selections do not highlight words.
buffer:set_sel(1, 3)
pos = buffer:indicator_end(ui.INDIC_HIGHLIGHT, 2)
@@ -1850,6 +1856,24 @@ function test_ui_highlight_word()
assert(buffer:is_range_word(buffer.selection_start, buffer.selection_end))
pos = buffer:indicator_end(ui.INDIC_HIGHLIGHT, 2)
assert_equal(pos, 1) -- no highlights
+ -- Verify current word highlighting.
+ ui.highlight_words = ui.HIGHLIGHT_CURRENT
+ buffer:goto_pos(1)
+ ui.update()
+ verify_foo()
+ buffer:line_down()
+ ui.update()
+ verify{buffer:position_from_line(LINE(2))}
+ buffer:line_down()
+ ui.update()
+ verify{buffer:position_from_line(LINE(3)), buffer:position_from_line(LINE(4)) + 9}
+ buffer:word_right()
+ ui.update()
+ verify_foo()
+ buffer:char_left()
+ ui.update()
+ pos = buffer:indicator_end(ui.INDIC_HIGHLIGHT, 2)
+ assert_equal(pos, 1) -- no highlights
buffer:close(true)
ui.highlight_words = highlight -- reset
end