SciTE4AutoHotkey extension - Count occurrences of word

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
haichen
Posts: 631
Joined: 09 Feb 2014, 08:24

SciTE4AutoHotkey extension - Count occurrences of word

15 Feb 2015, 11:39

I found a way to count the occurrences of a doubleclicked word in the document.
The Number of occurrences is then shown in the statusbar.

There are two parts.

First append this to ahk.lua:
I know you shouldn't do that because changes are overwritten on updates,
but I don't know another place to put it.

Code: Select all


-- from http://lua-users.org/wiki/SciteMarkWord

function clearOccurrences()
    scite.SendEditor(SCI_SETINDICATORCURRENT, 0)
    scite.SendEditor(SCI_INDICATORCLEARRANGE, 0, editor.Length)
end

function markOccurrences()
    if editor.SelectionStart == editor.SelectionEnd then
        return
    end
    clearOccurrences()
    scite.SendEditor(SCI_INDICSETSTYLE, 0, INDIC_ROUNDBOX)
    scite.SendEditor(SCI_INDICSETFORE, 0, 255)
    local txt = GetCurrentWord()
    local count = 0
    local flags = SCFIND_WHOLEWORD
    local s,e = editor:findtext(txt,flags,0)
    while s do
        scite.SendEditor(SCI_INDICATORFILLRANGE, s, e - s)
        s,e = editor:findtext(txt,flags,e+1)
        -- added from me
        count = count +1
       --
    end
    -- added from me
    props['countedOccurrences'] = count
    props['markedWord'] = txt
    --
    return 
end

function isWordChar(char)
    local strChar = string.char(char)
    local beginIndex = string.find(strChar, '%w')
    if beginIndex ~= nil then
        return true
    end
    if strChar == '_' or strChar == '$' then
        return true
    end
    
    return false
end

function GetCurrentWord()
    local beginPos = editor.CurrentPos
    local endPos = beginPos
    if editor.SelectionStart ~= editor.SelectionEnd then
        return editor:GetSelText()
    end
    while isWordChar(editor.CharAt[beginPos-1]) do
        beginPos = beginPos - 1
    end
    while isWordChar(editor.CharAt[endPos]) do
        endPos = endPos + 1
    end
    return editor:textrange(beginPos,endPos)
end

-- Add user event handler OnDoubleClick
-- found somewhere
local old_OnDoubleClick = OnDoubleClick
function OnDoubleClick(shift, ctrl, alt)
        local result
        if old_OnDoubleClick then result = old_OnDoubleClick(shift, ctrl, alt) end
        if markOccurrences() then return true end
        return result
end
then open SciteUser.properties
and add:

Code: Select all

highlight.current.word=1
statusbar.text.1=\
Line: $(LineNumber) | Column: $(ColumnNumber) | $(OverType) | ($(EOLMode)) | $(FileAttr)  |  $(countedOccurrences) Occurrences of "$(markedWord)" found
Restart SciTE4AutoHotkey and doubleclick on a word.

Perhaps fincs can add something like this to Scite4Autohotkey.
Especially for the search it would be nice to have a counter.
I know nothing about lua and scite, so i can't help if there are questions. Sorry.
But nevertheless i hope this could be helpful.
User avatar
fincs
Posts: 527
Joined: 30 Sep 2013, 14:17
Location: Seville, Spain
Contact:

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

15 Feb 2015, 12:23

haichen wrote:I know you shouldn't do that because changes are overwritten on updates,
but I don't know another place to put it.
Right click on Toolbar > Edit User Lua script. Also, you should use RegisterEvents() instead of manually overwriting event handlers.

Code: Select all

local events = {
    OnDoubleClick = function(shift, ctrl, alt)
        if markOccurrences() then return true end
        return false
    end
}
RegisterEvents(events)
You may be interested in the SciTE4AHK Extension mechanism, which allows you to more easily write these kinds of things.
fincs
Windows 11 Pro (Version 22H2) | AMD Ryzen 7 3700X with 32 GB of RAM | AutoHotkey v2.0.0 + v1.1.36.02
Get SciTE4AutoHotkey v3.1.0 - [My project list]
User avatar
haichen
Posts: 631
Joined: 09 Feb 2014, 08:24

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

16 Feb 2015, 02:36

Thanks for your advice!
It was quite easy to make an extension. ( i always forget the right click on Toolbar).
I think i must have a look at lua.
User avatar
empardopo
Posts: 336
Joined: 06 Oct 2013, 12:50
Location: Spain
Contact:

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

16 Feb 2015, 03:18

haichen wrote:Thanks for your advice!
It was quite easy to make an extension. ( i always forget the right click on Toolbar).
I think i must have a look at lua.
How you could do the same but with an extension?
Everything is possible!
User avatar
haichen
Posts: 631
Joined: 09 Feb 2014, 08:24

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

16 Feb 2015, 04:24

I changed my code to count marked text (without doublclick)

Code: Select all

function clearOccurrences()
    scite.SendEditor(SCI_SETINDICATORCURRENT, 0)
    scite.SendEditor(SCI_INDICATORCLEARRANGE, 0, editor.Length)
end

function markOccurrences()
    if editor.SelectionStart == editor.SelectionEnd then
        return
    end
    clearOccurrences()
    scite.SendEditor(SCI_INDICSETSTYLE, 0, INDIC_ROUNDBOX)
    scite.SendEditor(SCI_INDICSETFORE, 0, 255)
    local txt = editor:GetSelText()
    local count = 0
    local flags = SCFIND_MATCHCASE
    local s,e = editor:findtext(txt,flags,0)
    while s do
        scite.SendEditor(SCI_INDICATORFILLRANGE, s, e - s)
        s,e = editor:findtext(txt,flags,e+1)
        count = count +1
    end
    props['countedOccurrences'] = count
    props['markedWord'] = txt
    return 
end

-- Add user event handler OnDoubleClick
local events = {
    OnUpdateUI = function(shift, ctrl, alt)
        if markOccurrences() then return true end
        return false
    end
}

RegisterEvents(events)
@ empardopo
Follow the way to create a new extension described in fincs link. Activate "has custom Lua script".
Find the extension in %SciTEProfileDir%\Extensions folder (ex.: C:\Users\user\Documents\AutoHotkey\SciTE\Extensions\extensionname\ ).
Copy the above code to extension.lua, save it and then restart SciTE4Autohotkey.
Dont forget the statusbar code in SciteUser.properties
User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

17 Feb 2015, 15:37

haichen: I really like your count and highlighting of the other instances, but I have a couple questions:

How do you clear the highlighting?

Is it supposed give sort of a preview highlighting of a word the cursor is on but hasn't selected? Whatever word the cursor is on, not even with any selection made, it highlights the word and all other instances of it in a slightly darker color (without actually fully selecting it and giving the occurrence count).
User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

17 Feb 2015, 20:35

boiler wrote:Is it supposed give sort of a preview highlighting of a word the cursor is on but hasn't selected? Whatever word the cursor is on, not even with any selection made, it highlights the word and all other instances of it in a slightly darker color (without actually fully selecting it and giving the occurrence count).
I got rid of this feature which was really bugging me by removing highlight.current.word=1 (or setting it to 0).

I'd still like to know how to clear the highlighting for the last found matches. They stay highlighted until you select something else, which means you're stuck with things always being highlighted all over the screen.
User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

17 Feb 2015, 20:51

I figured out how to get all the highlights to clear after the selection is no longer made. In extension.lua, add clearOccurences() after the if statement that checks to see if the editor selection start and end are the same (i.e., no selection is made).

Code: Select all

function markOccurrences()
	if editor.SelectionStart == editor.SelectionEnd then
		clearOccurrences()
		return
	end
(I realize this turned out to be a bunch of posts answering my own questions. :D But I thought I should post what I came up with in case it helps anyone else and so no one spends time trying to figure it out.)
User avatar
haichen
Posts: 631
Joined: 09 Feb 2014, 08:24

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

18 Feb 2015, 02:16

Yesterday i used it the whole day. But didn't noticed the problem. May be i'm little blind. Sorry. Thanks for posting the solution! Its much better now.
:-) haichen
User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

18 Feb 2015, 11:59

I found that the occurrence count extension was causing SciTE4AutoHotkey to crash when I used column editing. Anyone else having this problem? Save your work before trying it! When I removed the extension, no crashes.
User avatar
haichen
Posts: 631
Joined: 09 Feb 2014, 08:24

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

18 Feb 2015, 13:07

Yes I get a freezing and then it crashes. Sorry for that! My only idea is that the script should not work when using alt ctrl. At the Moment i don't know how to do that.

My knowledge of Lua is very limited.
Once more my Apology for this crash.

So no one should use this at the moment!
User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

18 Feb 2015, 15:24

No problem. It's a nice capability, so it would be great if it can be fixed. I can look into it, but I'm not sure I'll be able to do much with it since I don't know Lua beyond what I learned to make a few mods to it.
User avatar
haichen
Posts: 631
Joined: 09 Feb 2014, 08:24

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

21 Feb 2015, 07:42

This Luacode seems to do it without crash:

Code: Select all

function clearOccurrences()
    scite.SendEditor(SCI_SETINDICATORCURRENT, 0)
    scite.SendEditor(SCI_INDICATORCLEARRANGE, 0, editor.Length)
end


function markOccurrences()
    if editor.SelectionStart == editor.SelectionEnd then
		clearOccurrences()
        return
    end
    clearOccurrences()
    scite.SendEditor(SCI_INDICSETSTYLE, 0, INDIC_ROUNDBOX)
    scite.SendEditor(SCI_INDICSETFORE, 0, 255)
    local txt = editor:GetSelText()
    local count = 0
    local dirty = 100000
    local flags = SCFIND_MATCHCASE
    local s,e = editor:findtext(txt,flags,0)
	while e do
	    dirty=dirty-1
	    if dirty<1 then break end
		scite.SendEditor(SCI_INDICATORFILLRANGE, s, e - s)
		s,e = editor:findtext(txt,flags,e+1)
		count = count +1
	end

    props['countedOccurrences'] = count
    props['markedWord'] = txt
    return 
end

-- Add user event handler OnDoubleClick
local events = {
    OnUpdateUI = function(shift,ctrl,alt)
    if markOccurrences() then     return true     end
    return false
    end
}

RegisterEvents(events)

The problem is in the Whileloop. While columnediting the loop does not end. You can see a really dirty solution. I dont find the real error. S and e are sometimes 'nil', but thats not the real problem. At the Moment i can't do more.
But it works ..hopefully..
User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

21 Feb 2015, 15:23

Thanks, haichen! It works well for me. I like having this capability again. I think it's a very nice addition to the editor.

I'll share a couple mods I made that I think are useful:

To make it so the status bar doesn't continue to show the count and the selected text after it's no longer selected and also to make it say "No occurrences" when there are none, I changed the first part in the markOccurrences() function to this: (added two lines before the return)

Code: Select all

    if editor.SelectionStart == editor.SelectionEnd then
		clearOccurrences()
		props['countedOccurrences'] = 'No'
		props['markedWord'] = ''
		return
	end
And to limit how much text is shown in the status bar when it gets long (over 40 characters), I use just the first 40 characters and add "..." by adding this if statement right before the final return of the function:

Code: Select all

	if (editor.SelectionEnd - editor.SelectionStart) > 40 then
		props['markedWord'] = string.sub(txt,1,40) .. '...'
	end

User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

21 Feb 2015, 15:31

One other change I made that is totally personal preference is that I like matching case insensitive since AHK is case insensitive, so I change local flags = SCFIND_MATCHCASE to local flags = 0
User avatar
haichen
Posts: 631
Joined: 09 Feb 2014, 08:24

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

22 Feb 2015, 04:00

Very nice boiler! I changed my code according your proposals.
Summary:
com.haichen.CountMarkedWords.s4x is an Extension for sciTE4Autohotkey.
It counts all marked ocurrences of a text, independently how it is marked (by hand or search).
The result is shown in the statusbar

Download the extension as file:
com.haichen.CountMarkedWords.s4x
After Right click on Toolbar > Extensions > Extensionmanager you can add the extensionfile with "Install Extension"

in Extras > User-settings (filename is SciteUser.properties) you have to add

Code: Select all

highlight.current.word=1
statusbar.text.1=\
Line: $(LineNumber) | Column: $(ColumnNumber) | $(OverType) | ($(EOLMode)) | $(FileAttr)  |  $(countedOccurrences) Occurrences of "$(markedWord)" found
till ...FileAttr) it's the code for the standard Statusbar display.

Special thanks to fincs and boiler.
ozzii
Posts: 481
Joined: 30 Oct 2013, 06:04

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

23 Feb 2015, 04:57

Download the extension as file:
com.haichen.CountMarkedWords.s4x
After Right click on Toolbar > Extensions > Extensionmanager you can add the extensionfile with "Install Extension"
[/quote]
For me the file is empty. Can you add the code here?
User avatar
haichen
Posts: 631
Joined: 09 Feb 2014, 08:24

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

23 Feb 2015, 06:36

Sorry for that Ozzii, it was the first time i used my 1blu-drive. I am sure i tested the download.
Here a new try with a dropboxlink
com.haichen.CountMarkedWords.s4x

And here is the whole lua script

Code: Select all

-- Lua script specific to this extension


-- derived from
-- http://lua-users.org/wiki/SciteMarkWord
function clearOccurrences()
    scite.SendEditor(SCI_SETINDICATORCURRENT, 0)
    scite.SendEditor(SCI_INDICATORCLEARRANGE, 0, editor.Length)
end


function markOccurrences()
    if editor.SelectionStart == editor.SelectionEnd then
		clearOccurrences()
		props['countedOccurrences'] = 'No'
        props['markedWord'] = ''
        return
    end
    clearOccurrences()
    scite.SendEditor(SCI_INDICSETSTYLE, 0, INDIC_ROUNDBOX)
    scite.SendEditor(SCI_INDICSETFORE, 0, 255)
    local txt = editor:GetSelText()
    local count = 0
    local dirty = 100000
    local flags = 0 --SCFIND_MATCHCASE
    local s,e = editor:findtext(txt,flags,0)
	while e do
	    dirty=dirty-1
	    if dirty<1 then break end
		scite.SendEditor(SCI_INDICATORFILLRANGE, s, e - s)
		s,e = editor:findtext(txt,flags,e+1)
		count = count +1
	end

    props['countedOccurrences'] = count
    props['markedWord'] = txt
    if (editor.SelectionEnd - editor.SelectionStart) > 40 then
		props['markedWord'] = string.sub(txt,1,40) .. '...'
    end
    return 
end

-- Add user event handler OnDoubleClick
local events = {
    OnUpdateUI = function(shift,ctrl,alt)
    if markOccurrences() then     return true     end
    return false
    end
}

RegisterEvents(events)

Here i explained it in short, how to build the extension.

haichen
ozzii
Posts: 481
Joined: 30 Oct 2013, 06:04

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

24 Feb 2015, 02:09

Thanks haichen now it's OK.
User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: SciTE4AutoHotkey v3.0.06.01 [Updated October 12 2014]

24 Feb 2015, 08:25

haichen: Here's one last mod I made to your Lua script that makes CountMarkedWords perfect for me now. Maybe it's more pronounced for me because my editor color scheme is a dark background, but I only want the highlight color for the matches it finds to be on the other matches, not superimposed over the original selection because then you get a combination of your selection highlighting and this match highlighting. Plus, it looked a little strange when selecting multiple lines of text and the linefeed character is highlighted differently from the rest of the text. So I added this if statement around one line in your while loop:

Code: Select all

        if e < editor.CurrentPos or s > editor.CurrentPos then
            scite.SendEditor(SCI_INDICATORFILLRANGE, s, e - s)
        end
Now I have separate control over highlighting of selected text and matched text. In your code, I changed the highlight color and added a line for controlling the alpha channel (transparency) that I like on my dark background.

Code: Select all

    scite.SendEditor(SCI_INDICSETFORE, 0, 0xCCFFFF)
    scite.SendEditor(SCI_INDICSETALPHA, 0, 100)
Thanks again for the great feature.

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 119 guests