Page 1 of 3

SciTE4AutoHotkey extension - Count occurrences of word

Posted: 15 Feb 2015, 11:39
by haichen
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.

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

Posted: 15 Feb 2015, 12:23
by fincs
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.

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

Posted: 16 Feb 2015, 02:36
by haichen
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.

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

Posted: 16 Feb 2015, 03:18
by empardopo
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?

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

Posted: 16 Feb 2015, 04:24
by haichen
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

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

Posted: 17 Feb 2015, 15:37
by boiler
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).

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

Posted: 17 Feb 2015, 20:35
by boiler
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.

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

Posted: 17 Feb 2015, 20:51
by boiler
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.)

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

Posted: 18 Feb 2015, 02:16
by haichen
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

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

Posted: 18 Feb 2015, 11:59
by boiler
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.

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

Posted: 18 Feb 2015, 13:07
by haichen
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!

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

Posted: 18 Feb 2015, 15:24
by boiler
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.

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

Posted: 21 Feb 2015, 07:42
by haichen
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..

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

Posted: 21 Feb 2015, 15:23
by boiler
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


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

Posted: 21 Feb 2015, 15:31
by boiler
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

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

Posted: 22 Feb 2015, 04:00
by haichen
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.

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

Posted: 23 Feb 2015, 04:57
by ozzii
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?

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

Posted: 23 Feb 2015, 06:36
by haichen
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

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

Posted: 24 Feb 2015, 02:09
by ozzii
Thanks haichen now it's OK.

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

Posted: 24 Feb 2015, 08:25
by boiler
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.