Far3: Macro to select same/similar file on other panel

Here you can discuss any topic concerning Far macro commands.
Post Reply
farman
Posts: 118
Joined: Thu 03 Sep, 2009 11:32

Far3: Macro to select same/similar file on other panel

Post by farman » Tue 05 Mar, 2013 15:43

Hi,
while playing around with lua I tried to write a more accurate macro to select same/similar file on other panel. And then I got in a lot of trouble while comparing filenames:
- Undocumented or rarely documented FAR-api (and the not existing english docu)
- ASCII/ANSI/Unicode support of lua/FAR
- Comparing filenames and finding the right positon of the similar filename in FAR
To make it short: I tried a lot, cried out sometimes and ended up with this "best" version.

But what I really like to have is a little more. Doing a search for 2 example files ('1Filename4a.txt', '2Filename.txt') in Passive panel should lead to the green results:
  • 1Filename1a.txt << Fastsearch selects this item for '1Filename4a.txt' ...>>
    1Filename1b.txt
    1Filename1c.txt << ... but should select the nearest Filename for '1Filename4a.txt' >>
    << '2Filename.txt' should be "virtually" placed here (Fastsearch can't do that) >>
    3Filename9a.txt
    3Filename9b.txt
And of course this should work with unicode too. :)
If it is possible to make a macro for that, maybe someone knows how to do this?
Or it is better to pack up some beer, send it the coders and place a wish in mantis?

2013-04-15 Edit:
- Fixed the code to overcome the API limitations. Now using a static table for sorting purpose.
- Still using Fastsearch. If Fastsearch doesn't find the file then select nearest file

Code: Select all

------------------------------------------------------------------------------
--  Valid Filesystem UNICODE Chars: Space (32) to greek Omega (974)
--  Only chars that are defined in "Lucida Console". Sorted by name like FAR 3.0.3235 does
local FARSortOrder = {
127, 39, 42, 63, 45, 173, 32, 160, 33, 35, 36, 37, 38, 40, 41, 44, 46, 59, 64, 91, 93, 710, 94, 34, 95, 903, 96, 123, 125, 126, 161, 166, 168, 175,
713, 180, 184, 191, 711, 728, 729, 730, 731, 732, 733, 894, 900, 901, 43, 61, 177, 171, 187, 215, 247, 162, 163, 164, 165, 167, 169, 172, 174, 176,
181, 182, 183, 48, 188, 189, 190, 185, 49, 178, 50, 179, 51, 52, 53, 54, 55, 56, 57, 170, 192, 224, 193, 225, 194, 226, 195, 227, 196, 228, 197,
229, 256, 257, 258, 259, 260, 261, 506, 507, 65, 97, 198, 230, 508, 509, 66, 98, 199, 231, 262, 263, 264, 265, 266, 267, 268, 269, 67, 99, 208, 240,
270, 271, 272, 273, 68, 100, 200, 232, 201, 233, 202, 234, 203, 235, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 69, 101, 70, 102, 401, 402,
284, 285, 286, 287, 288, 289, 290, 291, 71, 103, 292, 293, 294, 295, 72, 104, 204, 236, 205, 237, 206, 238, 207, 239, 296, 297, 298, 299, 300, 301,
302, 303, 305, 73, 105, 304, 306, 307, 308, 309, 74, 106, 310, 311, 312, 75, 107, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 76, 108, 77, 109,
209, 241, 323, 324, 325, 326, 327, 328, 329, 78, 110, 330, 331, 186, 210, 242, 211, 243, 212, 244, 213, 245, 214, 246, 216, 248, 332, 333, 334, 335,
336, 337, 510, 511, 79, 111, 338, 339, 80, 112, 81, 113, 340, 341, 342, 343, 344, 345, 82, 114, 346, 347, 348, 349, 350, 351, 352, 353, 83, 115, 223,
383, 354, 355, 356, 357, 84, 116, 222, 254, 358, 359, 217, 249, 218, 250, 219, 251, 220, 252, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370,
371, 85, 117, 86, 118, 372, 373, 87, 119, 88, 120, 221, 253, 255, 376, 374, 375, 89, 121, 377, 378, 379, 380, 381, 382, 90, 122, 902, 940, 913, 945,
914, 946, 915, 947, 916, 948, 904, 941, 917, 949, 918, 950, 905, 942, 919, 951, 920, 952, 906, 943, 912, 921, 953, 938, 922, 954, 923, 955, 924, 956,
925, 957, 926, 958, 908, 927, 959, 928, 960, 929, 961, 931, 962, 963, 932, 964, 910, 933, 965, 939, 944, 934, 966, 935, 967, 936, 968, 911, 937, 969 }

------------------------------------------------------------------------------
function mysearch(IEnd, w1)
    for i=1,IEnd do
      if (FARSortOrder[i]==w1) then return i end  -- found
    end
   return 1                                       -- not found
end


------------------------------------------------------------------------------
Macro { description="*.Find selected file in passive panel";
        area="Shell Tree"; key="CtrlShiftLeft CtrlShiftRight"; flags="DisableOutput";
        action = function()
  if APanel.Type<=1 and PPanel.Type<=1 and PPanel.Visible then        -- 0=File panel, 1=folder tree
    s1=APanel.Current                                    -- active panel
    ---------------------------------------
    -- SEACRH 1: Select ".." / Using FastSearch
    ---------------------------------------
    if s1==".." then
      Keys("TAB HOME")                                   -- Switch PANEL !!! and select 1. item
      exit()
    else
      Keys("TAB HOME Alt<")                              -- Switch PANEL !!! and start FastSearch...
      print(s1)
      Keys("ESC")
    end
    ---------------------------------------
    -- SEACRH 2 (FastSearch didn't find same/similar filename)
    ---------------------------------------
    if APanel.CurPos==1 then                             -- Fastsearch didn't find anything
      bs1=s1:byte(1)                                     -- get value of 1. char
      local i1 = mysearch(#FARSortOrder,bs1)             -- Position of bs1 (PanelCurrent.1stChar) in table
      if i1==1 then exit() end                           -- not found (Cursor = HOME)
      local j=1
      local k=0   local kOld=0
      local c,    cOld
      for i=1,panel.GetPanelInfo(nil,1).ItemsNumber do
        c=panel.GetPanelItem(nil,1,i).FileName:byte(1)   -- searched char in table
        if c~=cOld then                                  -- not the same char... (behaves like Fastsearch)
          k = mysearch(i1,c)                             -- Position of FileName.1stChar in table
          if k>kOld then
            kOld = k
            j=i                                          -- remember CursorPos
            if kOld==i1-1 then break end                 -- preceding char found -> stop
          end
          cOld=c
        end
      end
      panel.RedrawPanel(nil,1,{CurrentItem=j,TopPanelItem=topItem})   -- SelctItem and Redraw ActivePanel
    end
  end
end;
}


Shmuel
Posts: 5101
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 11 times
Been thanked: 140 times

Re: Far3: Macro to select same/similar file on other panel

Post by Shmuel » Wed 06 Mar, 2013 21:46

farman

Fast search is not meant to do "approximate" searches. Its algorithm does very well what it is designed for but it cannot do arbitrary things. Moreover, criteria of proximity between 2 file names may vary widely. IMHO, you should not use fast search for this task, it is not suitable for it.

What you can do is the following: write a function whose input are 2 file names and whose output is a number that expresses the "degree of proximity" between the 2 names (as you understand it, as it is very subjective). Then iterate on all files in the panel, calling this function for each file against a "reference" file. Then select the file that gave the maximal number during that iteration.

BTW: never use 0 as an offset in string.sub. Offsets may be either positive or negative but never 0. If it works then it is by chance.

BTW2: if you want Unicode rather than ASCII, you should use operator : on strings, i.e.

Code: Select all

string.upper(string.sub(FileName,1,1)) --> ASCII
FileName:sub(1,1):upper()              --> UTF-8

farman
Posts: 118
Joined: Thu 03 Sep, 2009 11:32

Re: Far3: Macro to select same/similar file on other panel

Post by farman » Thu 07 Mar, 2013 07:13

Thanks, Shmuel. I came to the same conclusion concerning FastSearch.
One thing I'm still not sure of is the compare algorithm. I would like to use the same sort algorithm in FAR. Do I have to test this out or is there a place where I can find information about that?
I thought of another way to solve this. Is it possible to place my SearchedFilename "virtually" in PassivePanel, let FAR do the work and then get the position etc.?

Shmuel
Posts: 5101
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 11 times
Been thanked: 140 times

Re: Far3: Macro to select same/similar file on other panel

Post by Shmuel » Thu 07 Mar, 2013 10:34

farman wrote:One thing I'm still not sure of is the compare algorithm. I would like to use the same sort algorithm in FAR. Do I have to test this out or is there a place where I can find information about that?
See function far.GetPanelInfo, specifically fields SortMode and Flags.
farman wrote:I thought of another way to solve this. Is it possible to place my SearchedFilename "virtually" in PassivePanel, let FAR do the work and then get the position etc.?
I don't think it is possible.

farman
Posts: 118
Joined: Thu 03 Sep, 2009 11:32

Re: Far3: Macro to select same/similar file on other panel

Post by farman » Mon 15 Apr, 2013 07:23

I fixed the macro to overcome API limitations.
Fastsearch is still used. If Fastsearch does not find the file (= first letter of filename doesn't exist) then Macro searches for the next nearest file (first letter).
Maybe someone knows a better way.
Enjoy.

Post Reply

Return to “Macro Commands Discussions”