Реализовать дерево директорий панельным модулем на Луа

Здесь обсуждается всё, что касается макросов.
buniak_a_h
Posts: 3205
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 169 times
Been thanked: 468 times
Contact:

Реализовать дерево директорий панельным модулем на Луа

Post by buniak_a_h »

citRiks wrote: Sun 08 Mar, 2020 21:37
buniak_a_h wrote: Sat 07 Mar, 2020 19:41 Я начинал делать дерево в виде панельного модуля. Вот это мне показалось наиболее удобным. Но… Отвлекли на работе.
ну положите куда-нибудь на видное место если там есть хоть что-то полезное, может кто-нибудь продолжит
Спасибо citRiks-у за наводку на tree.com - давно забытая утилитка. Получился довольно небольшой и вполне пригодный модуль. Позволяет открывать-закрывать узлы дерева, задавать глубину, на которую первоначально открываются узлы; просматривать в пассивной панели текущую папку и переходить в панели дерева на выбранную папку.



Чего может не хватать:
  • обновления дерева (по таймеру, например);
  • вывода характеристик (суммарный размер поддерева, самого нового файла, количество файлов).
  • Что ещё - не знаю.
Если кому-нить это интересно, перечисленные недоделки я по возможности доделаю. Также принимаются предложения, чего может ещё не хватать для нормальной работы. Но так-то вроде вполне удобненько получилось … :-)
Опять же если будут добровольцы - локализацию и перевод хелпа были бы полезны. Если скрипт кому-нить покажется полезным …

Версия 2.6.6.
  1. Исправлен «снос» имени текущей папки в командную строку: теперь оно заменяет отмеченную часть командной строки или (если ничего не отмечено) вставляется в текущую позицию строки.
  2. Исправлена мелкая неточность: вопрос о пересоздании кэша задаётся только в том случае, если задан период актуализации кэша
TreePanel_2_6_6.7z
(31.08 KiB) Downloaded 48 times


1)Корневой каталог - каталог, который вместе с вложенными показан на дереве.
Last edited by buniak_a_h on Mon 14 Dec, 2020 07:40, edited 37 times in total.
buniak_a_h
Posts: 3205
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 169 times
Been thanked: 468 times
Contact:

Реализовать дерево директорий панельным модулем на Луа

Post by buniak_a_h »

Latest post of the previous page:

Вышла версия 2.6.2. В этой версии:
  1. Изменены некоторые хоткеи. В частности, CtrlEnter теперь не открывает текущую папку на пассивной панели, а сносит имя текущей папки в командную строку (стандартное действие для панели); CtrlF не открывает диалог поиска, а сносит полный путь к текущей папке в командную строку (тоже стандартное действие), а поиск начинается по клавише F7.
  2. Исправлены неточности первоначального позиционирования в дереве.
  3. Панели плагинов MultiArc и Observer приравнены (с точки зрения ограничения) к панели плагина ArcLite.
  4. Рефакторинг.
DV
Posts: 446
Joined: Mon 07 Aug, 2006 08:23
Has thanked: 24 times
Been thanked: 15 times

Реализовать дерево директорий панельным модулем на Луа

Post by DV »

Спасибо за обновление!
Случайно обнаружил, что если в панели поиска (F7) сначала выбрать режим "Фильтр" и затем в отфильтрованной панели дерева нажать на любом элементе стрелку влево (клавишу "стрелка влево"), то получаем ошибку: "TreePanel.lua:1026: attempt to index local 'ItemI' (a nil value)".
Также не понял, возможно ли из режима "Фильтр" вернуться обратно в режим "Поиск", чтобы в панели дерева отображались все элементы, а не только отфильтрованные.
buniak_a_h
Posts: 3205
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 169 times
Been thanked: 468 times
Contact:

Реализовать дерево директорий панельным модулем на Луа

Post by buniak_a_h »

DV, на режим фильтрации я не получил ни одной реакции, думал - никого не интересует. Сделал первый (стартовый) вариант и оставил со знакомыми мне недоделками. Ок, займусь.
Для снятия фильтра, вроде, работает такой алгоритм: инициировать поиск, там мышкой переключиться на фильтр Или просто закрыть диалог фильтрации (Esc, Enter) и инициировать его снова (в "древесной" панели это - Ctrl+F7). Неудобно, конечно. Просто пока не приходит в голову, как лучше. Очень не хочется городить полный диалог. Ну, раз есть спрос - буду думать.
DV
Posts: 446
Joined: Mon 07 Aug, 2006 08:23
Has thanked: 24 times
Been thanked: 15 times

Реализовать дерево директорий панельным модулем на Луа

Post by DV »

Интуитивно я предполагал, что изменение режима "Поиск" на "Фильтр" (и наоборот) нажатием мышки или выбором с клавиатуры моментально меняет отображение панели дерева (в режиме "Поиск" - все элементы, в режиме "Фильтр" - только отфильтрованные).
buniak_a_h
Posts: 3205
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 169 times
Been thanked: 468 times
Contact:

Реализовать дерево директорий панельным модулем на Луа

Post by buniak_a_h »

Вышла версия 2.6.3. В ней:
  1. Исправлена ошибка, приводившая к вылету при активном фильтре и попытке выйти на узел верхнего уровня,
    если он (узел) не виден из-за наложенного фильтра. Ошибка описана тут.
  2. Реализовано составление дерева для контейнеров, не поддерживаемых утилитой 7z. Проверено для случаев: контейнер - msi-пакет и виртуальный диск для vmware; открыты плагином Observer (отдельная благодарность citRiks-у за напоминание о far.Host)
  3. Реализовано закрытие дерева по повторному нажатию Ctrl+T (если дерево уже открыто)
  4. Оптимизация, рефакторинг
Last edited by buniak_a_h on Sun 15 Nov, 2020 12:16, edited 1 time in total.
buniak_a_h
Posts: 3205
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 169 times
Been thanked: 468 times
Contact:

Реализовать дерево директорий панельным модулем на Луа

Post by buniak_a_h »

Вышла версия 2.6.4. В версии:
  1. Реализована возможность копирования файла в папку, соответствующую текущему узлу дерева. Имя папки назначения подставляется в диалог копирования вместо имени формата папки плагина.
  2. Реализован переход на узел того же уровня, имеющий того же предка (sibling node). Для этого предусмотрены клавиши Alt+↑ и Alt+↓
  3. Добавлена возможность выводить столбец с количеством файлов в папке, соответствующей узлу дерева.
Last edited by buniak_a_h on Mon 16 Nov, 2020 03:25, edited 1 time in total.
buniak_a_h
Posts: 3205
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 169 times
Been thanked: 468 times
Contact:

Реализовать дерево директорий панельным модулем на Луа

Post by buniak_a_h »

Вышла версия 2.6.5
В версии:
  1. Исправлена ошибка, возникавшая при перестроении всего дерева по клавише Ctrl+R (обновить). Кроме того, по этой клавише возможно обновление кэша.
  2. При выходе из дерева состояние другой панели теперь восстанавливается только в случае, если включено немедленное открытие текущего каталога на противоположной панели.
  3. Добавлен минимальный контроль актуальности данных о папке в кэше: если в корневой папке имеются подпапки, а дерево формируется пустым, то выводится сообщение о критической неактуальности кэша и предлагается его перестроить. В случае отказа только перестраивается в памяти ветка корневого каталога дерева.
  4. При обновлении дерева по Ctrl+R также предлагается обновить кэш диска.
  5. Экспериментально!] При смене каталога на другой (не_древесной) панели (если она активна) указатель в дереве переносится на соответствующий узел дерева; при этом он помечается символом «►».
User avatar
citRiks
Posts: 1612
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 502 times
Been thanked: 95 times

Реализовать дерево директорий панельным модулем на Луа

Post by citRiks »

Спасибо что улучшаете :)
надо бы запилить что-то менее потребляющее память,
Мне показалось что "древесные" структуры хорошо (эффективно) хранятся в CDB
http://cr.yp.to/cdb.html
https://github.com/istr/lua-cdb
И сделать "ленивую" (отложенную) загрузку из CDB по мере переходов по дереву.
хотя это может быть мой лишний перфекционизм
Надеюсь когда-нибудь сам доберусь до этого
А кто не поверит в наше миролюбие, / Тот кровью умоется. / И будет такая борьба за мир, / Что камня на камне не останется.
buniak_a_h
Posts: 3205
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 169 times
Been thanked: 468 times
Contact:

Реализовать дерево директорий панельным модулем на Луа

Post by buniak_a_h »

citRiks, несколько вопросов.
1. Чем CDB лучше SQLite? или это вопрос из серии "что лучше - красное или мягкое"?
2. Чем в плане потребления памяти поможет хранение в БД, если применяется «отложенная загрузка»? Или имеется в виду случай, когда не потребуется загрузка дерева всего диска?
К первому вопросу: очень не хочется подключать какие-то "левые" продукты. Чем хорош макрос: всё доступно и достаточно. Но если SQLite, хоть и не входит в поставку FAR-а, но более распространён. Хотя мне это всё равно не нравится…
buniak_a_h
Posts: 3205
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 169 times
Been thanked: 468 times
Contact:

Реализовать дерево директорий панельным модулем на Луа

Post by buniak_a_h »

citRiks, Вы писали где-то про изменение порядка построения дерева (не вглубь, а вширь). В принципе, я реализовал такой подход, но наткнулся на несколько "особенностей", сводящих преимущества на "нет":
1. far.RecursiveSearch с флагом FRS_RECUR обеспечивает обход всего дерева за один вызов функции, но, есессно, "вглубь". Для того, чтобы реализовать обход диска "вширь", надо не использовать рекурсивный поиск внутри функции, а читать только список одного каталога, затем снова вызывать far.RecursiveSearch для получения списка папок первого уровня, затем для каждой папки 1-го уровня вызывать снова far.RecursiveSearch для получения списка папок 2-го уровня и т.д. При этом теряется преимущество эффективной реализации far.RecursiveSearch, что резко снижает быстродействие.
2. На системном диске имеется "рекурсивная" организация папок и линков таким образом, что просто обход зацикливается. Либо надо запрещать обход линков, либо запоминать реальные пути и проверять, были ли мы здесь. Первый вариант - линки не отобразятся дереве; второй - тормоза кошмарные. Как это делает far.RecursiveSearch - я не проверял. Но как-то делает.
P/S. Чтобы запретить сканирование симлинков достаточно просто не указывать флаг FRS_SCANSYMLINK. А для идеологии "вширь" надо проверять именно атрибуты папки. Это наверняка ещё замедлит процедуру.
Резюмирую.
Единственный способ получить выигрыш из чтения папок "вширь" - это начальное чтение на небольшую глубину, а затем дочитывание в фоне. Но Вы сами почему-то были резко против фонового чтения…
User avatar
citRiks
Posts: 1612
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 502 times
Been thanked: 95 times

Реализовать дерево директорий панельным модулем на Луа

Post by citRiks »

buniak_a_h,
Приветствую, извиняюсь за отсутствие, отсутствие произошло не потому что тема не интересна, тема интересна и полезна, и многим.
Чем CDB лучше SQLite? или это вопрос из серии "что лучше - красное или мягкое"?
Я как-то увидел что во всяких embedded и real-time софте используется частенько CDB там где нужно что-то иерархическое.
Скажу какое я впечатление получил от CDB, не особо вникая в него (к сож. недостаток времени и другие отвлекающие факторы)
Кажется что дело в том что CDB и более простой и более направленный на эту потребность, и не грузит все в память, или грузит самый минимум, и может эффективно доставать иерархии с диска.
Далее, насколько я знаю, для эффективного применения SQLite нужно собственно знание языка SQL вкупе с особенностями диалекта SQLite.
У CDB в этом смысле нет языка, а набор простых АПИ для лазания по иерархиям, т.е. теоретически наверное проще чем изучать SQL для тех кто с ним изначально не очень дружит.
Ну это мои прикидки пользы от CDB, на базе впечатлений от проекта Луа который мне попался, и в котором применялся CDB.
2. Чем в плане потребления памяти поможет хранение в БД, если применяется «отложенная загрузка»? Или имеется в виду случай, когда не потребуется загрузка дерева всего диска?
Приличные базы данных обычно не грузят всю базу в память, а только те записи которые понадобились, т.е. например, если нам нужен только топ-левел (верхний уровень увидеть), то прочитаются с диска и окажутся в памяти только эти топ-левел записи, что эффективеннее чем при любом обращении загружать все в память.
К первому вопросу: очень не хочется подключать какие-то "левые" продукты. Чем хорош макрос: всё доступно и достаточно. Но если SQLite, хоть и не входит в поставку FAR-а, но более распространён. Хотя мне это всё равно не нравится…
Сам SQLite сидит в ФАРе, и DrKnS вроде собирался вынести его DLL наружу.
Если вам проще в SQLite то это тоже хорошо будет я думаю, и очень может что не хуже чем CDB.
Я разделяю ваше предубеждение от влючения разных зависимостей, это всегда добавляет "точек ломучести" (забыл правильный научный термин для этого)
Вместе с этим, ради эффективности, частенько приходится скрепя сердце добавлять такое что-нибудь, что в принципе неизбежно
Last edited by citRiks on Thu 03 Dec, 2020 08:56, edited 1 time in total.
А кто не поверит в наше миролюбие, / Тот кровью умоется. / И будет такая борьба за мир, / Что камня на камне не останется.
User avatar
citRiks
Posts: 1612
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 502 times
Been thanked: 95 times

Реализовать дерево директорий панельным модулем на Луа

Post by citRiks »

buniak_a_h wrote: Fri 27 Nov, 2020 00:15 Единственный способ получить выигрыш из чтения папок "вширь" - это начальное чтение на небольшую глубину, а затем дочитывание в фоне. Но Вы сами почему-то были резко против фонового чтения…
надо будет подумать над вышеуказанными проблемами..
возможно вы правы, но для меня странновато что нельзя найти более эффективный способ искать "послойно"
В фоне думаю что можно искать, при условии что пользователю видно что идет фоновый процесс, и что есть какой-то UI (кнопка, способ) остановить этот процесс вручную. Ну например когда уже найдено то что нужно, или просто отмена. А так безусловные (неотменяемые) какие-то фоновые операции "на всякий случай" как мне кажется не есть очень хорошо
А кто не поверит в наше миролюбие, / Тот кровью умоется. / И будет такая борьба за мир, / Что камня на камне не останется.
buniak_a_h
Posts: 3205
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 169 times
Been thanked: 468 times
Contact:

Реализовать дерево директорий панельным модулем на Луа

Post by buniak_a_h »

citRiks wrote: Thu 03 Dec, 2020 09:07 для меня странновато что нельзя найти более эффективный способ искать "послойно"
Даже чисто теоретически: для построения всего дерева надо составить список всех папок независимо от порядка обхода. Разница в том, что при обходе "вглубь" far.RecursiveSearch вызывается один раз, а собственно список делается на СИ (скорее всего). А при обходе вширь функцию надо вызывать столько раз, сколько имеется папок. Естественно, это менее эффективно. Вариант - написать свою процедуру на СИ (подключить через ffi), которая будет вызывать FindFirst-FindNext-FindClose для каждой папки из переданного списка. Там, наверно, можно вообще сделать реальное распараллеливание. Но для этого надо слишком вспоминать СИ.
citRiks wrote: Thu 03 Dec, 2020 09:07 безусловные (неотменяемые) какие-то фоновые операции
С одной стороны, они легко делаются отменяемыми. С другой, мне кто-то (по-моему, Дж.Доу или Харт) в другой теме написали, что фактически это - не реальная мультизадачость. Просто слайсы проц.времени. Т.е. выполняются они всё равно в головном потоке ФАРа. А тогда смысл только в том, что дочитывается, а юзер тем временем может работать.
С поиском - совсем беда. Не уверен, что есть смысл искать, пока дерево не загружено
Last edited by buniak_a_h on Thu 03 Dec, 2020 23:46, edited 1 time in total.
buniak_a_h
Posts: 3205
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 169 times
Been thanked: 468 times
Contact:

Реализовать дерево директорий панельным модулем на Луа

Post by buniak_a_h »

Выпустил версию 2.6.6. Мелкие доделки; основная задача - "зафиксировать" рабочую версию скрипта перед большими изменениями.
Что в версии:
  1. Исправлен «снос» имени текущей папки в командную строку: теперь оно заменяет отмеченную часть командной строки или (если ничего не отмечено) вставляется в текущую позицию строки.
  2. Исправлена мелкая неточность: вопрос о пересоздании кэша задаётся только в том случае, если задан период актуализации кэша
User avatar
citRiks
Posts: 1612
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 502 times
Been thanked: 95 times

Реализовать дерево директорий панельным модулем на Луа

Post by citRiks »

buniak_a_h wrote: Thu 03 Dec, 2020 14:39 Даже чисто теоретически: для построения всего дерева надо составить список всех папок независимо от порядка обхода. Разница в том, что при обходе "вглубь" far.RecursiveSearch вызывается один раз, а собственно список делается на СИ (скорее всего). А при обходе вширь функцию надо вызывать столько раз, сколько имеется папок. Естественно, это менее эффективно. Вариант - написать свою процедуру на СИ (подключить через ffi), которая будет вызывать FindFirst-FindNext-FindClose для каждой папки из переданного списка
не, если цель чтобы было все дерево, то тогда конечно оно без разницы рекурсивно или "в ширину" сначала.
Но я больше имел ввиду сценарий с вашим "поиск с переходом", чтобы вначале сразу находились верхние файлы.
Хоть у вас там ГУЯ с отменой все равно нет, но может когда нибудь добавите? :)
PS
А может эта функция будет эффективнее для нерекурсивных поисков?
far.GetDirList
https://api.farmanager.com/ru/service_f ... rlist.html

Code: Select all

lua:=far.GetDirList(".")
lua:LE(far.GetDirList("."))
PS #2
А еще есть LuaFileSystem, там полный коплект для работы с файлами,
может там будет поэффективнее, если проблема в медленности RecursiveSearch для множества нерекурсивных поисков
Last edited by citRiks on Sat 19 Dec, 2020 19:35, edited 2 times in total.
А кто не поверит в наше миролюбие, / Тот кровью умоется. / И будет такая борьба за мир, / Что камня на камне не останется.
buniak_a_h
Posts: 3205
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 169 times
Been thanked: 468 times
Contact:

Реализовать дерево директорий панельным модулем на Луа

Post by buniak_a_h »

citRiks,
1. Полный список мне не нужен - мне ж только папки нужны
2. По Esc функция снимается, но возвращает nil, а не тот список, что к моменту снятия накоплен.
3. В некоторых случаях структура, передаваемая в бэккол-функцию RecursiveSearch первым параметром, содержит больше информации, чем win.GetFileInfo. В результате я заменил последнюю на свою. Я не проверил, как заполняет эту структуру GetDirList.
4. Пока я всё это пишу, работает (уже минут 5, не засёк) far.GetDirList([[C:\]]). По-моему, моя сейчас быстрее строит дерево всего диска.
P/S. Уже минут 10… Думаю, она зациклилась из-за циклических линков на диске C:
Post Reply

Return to “Обсуждение макросов”