Задача WORDS-LIKE поиск слов в словаре nnCron

Обсуждение программ nnCron и nnCron LITE

Задача WORDS-LIKE поиск слов в словаре nnCron

Postby dothen » Mon, 14 Mar 2016, 23:27

Быстрый и удобный поиск слов.

Image

Code: Select all
# Файл:       nncron_wordslike.tab
# Автор:      dothen
# Дата:       07.05.2017
# Версия:     2.12
# Описание:
# Поиск слов в словаре nnCron и вывод на экран.
# Переделанный WORDS-LIKE

# Подключить плагин extwords.spf
# Подключить кронтаб nncron_extwords2.tab (http://www.nncron.ru/forums/viewtopic.php?f=5&t=13361#p35725)
# ------------------

# Если во входной строке есть пробелы и т.п. то берется первое слово в качестве фрагмента.
# Длинный фрагмент yкорачивается до 60 символов.
# Если найдено 50 и больше слов тогда список выводится сразу в блокнот.
# Если для поиска задать пустую строку или пробелы то получим все слова из словаря.
# В конце списка добавляется статистика.
# Чтобы выполнить поиск без учета регистра надо нажать Shift
# Можно искать с использованием регулярных выражений.  Примеры:    /get.*name/i    /^SAVE/    /rror$/

# Горячие клавиши:
# Win+W  -  Появляется диалоговое окно с предложением ввести часть слова. Если в буфере обмена есть текст то в поле ввода будут вставлены первые символы (максимум 60 если не было пробела).
# Win+Q  -  То же самое, только после отпускания клавиши Win автоматически выводится результат поиска (если окно имеет фокус).
# Можно подержать клавишу Win нажатой и переключить учет регистра (Shift), или закрыть окно, или деактивировать(мышкой или Win+(1-9) и т.п.).

# Задача сохраняет историю введенных слов.
# Открывается история в виде меню, двумя способами:
# 1) Down(стрелка вниз) когда окно с приглашением ввести слово активно.
# 2) LBM(левая клавиша мыши) в этом же окне на кнопке [развернуть].
# Константа wlmaxhistory устанавливает масштаб истории.

# Одновременно могут работать несколько задач (после вывода в блокнот задача завершается).
# Константа wlmaxcounter устанавливает число одновременно работающих задач и блокнотов.
# Закрытие окна с нажатой Shift вызывает закрытие всех окон и блокнотов, открытых из задачи.

# Задача не изменяет содержимое буфера обмена а только копирует из него текст.


<%


SCONSTANT WLWindowTitle1 Поиск слов в словаре nnCron
SCONSTANT WLWindowTitle2 Список найденных слов:     

WinGVI?
[IF] \ Если Vista или выше.
  SCONSTANT NotepadTitle Безымянный — Блокнот
[ELSE] \ Если XP или ниже.
  SCONSTANT NotepadTitle Безымянный - Блокнот
[THEN]

USER-VALUE WLFOUND \ Список найденных слов.
USER WLCOUNT       \ Количество найденных слов.
USER WLALLWORDS    \ Количество всех слов в словаре.
USER WLFULLWORD    \ Количество точно соответствующих слов.

64 USER-ARRAY WLFRAGMENT

10 CONSTANT wlmaxhistory  \ Число слов в истории.
4 CONSTANT wlmaxcounter   \ Число одновременно работающих задач.
0 VALUE <cron-node>  \ Адрес структуры CRON-NODE основной задачи. Для доступа из другой задачи, вместо вектора.

: WLTaskCounter ( -- n ) <cron-node> CRON-COUNTER @ ; \ Для работы в слове (WLWatchHKey), т.к. задача определена после него, т.е. имени еще нет в словаре.

: WLMaxNotepads? ( -- ? )
    PAD 0!
    FOR-WINDOWS: "%WLWindowTitle2%*"
      PAD 1+! \ Вместо PAD можно взять <FOUND-WINDOW> в качестве счетчика.
   ;FOR-WINDOWS
    PAD @ wlmaxcounter < 0=
;

: icase? ( -- ? ) VK_SHIFT KEY-PRESSED? ; \ Игнорировать регистр если TRUE

: XT_SEARCH ( -- xt ) icase? IF ['] ISEARCH ELSE ['] SEARCH THEN ;

: ReMatch ( a1 u1 amask umask -- 0 0 ? ) RE-MATCH 0 0 ROT ;

: XT-RE|SEARCH ( -- xt )
    WLFRAGMENT DUP C@ +    C@ [CHAR] / =
    WLFRAGMENT DUP C@ + 1- C@ [CHAR] / = OR
    WLFRAGMENT 1+          C@ [CHAR] / = AND
    IF ['] ReMatch ELSE XT_SEARCH THEN
;

: +WLFOUND ( a u -- ) WLFOUND +SPLACE ;

: WLADDREPORT ( xt -- )
    >R
    S" ____________"  +WLFOUND
    CRLF              +WLFOUND
    S" Найдено слов:" +WLFOUND
    HTAB              +WLFOUND
    WLCOUNT @ N>S     +WLFOUND
    R> ['] ReMatch =
    IF
      HTAB +WLFOUND S" Регулярное выражение" +WLFOUND
    ELSE
      icase?  IF HTAB +WLFOUND S" Без учета регистра" +WLFOUND THEN
    THEN
    CRLF              +WLFOUND
    S" Точных слов:"  +WLFOUND
    HTAB              +WLFOUND
    WLFULLWORD @ N>S  +WLFOUND
    CRLF              +WLFOUND
    S" Фрагмент:"     +WLFOUND
    HTAB              +WLFOUND
    WLFRAGMENT COUNT  +WLFOUND
    HTAB              +WLFOUND
    S" Длина: "       +WLFOUND
    WLFRAGMENT C@ N>S +WLFOUND
    CRLF              +WLFOUND
    S" Всего слов:"   +WLFOUND
    HTAB              +WLFOUND
    WLALLWORDS @ N>S  +WLFOUND
;

: (WordsLike) ( -- )
    WLCOUNT 0! WLALLWORDS 0!
    WLFOUND 0! WLFULLWORD 0!
    XT-RE|SEARCH >R
    CONTEXT @ @
    BEGIN ?DUP WHILE
      DUP COUNT WLFRAGMENT COUNT R@ EXECUTE
      IF
        2 PICK 1+ WLFRAGMENT C@ D= IF HTAB +WLFOUND WLFULLWORD 1+! THEN
        DUP COUNT +WLFOUND CRLF +WLFOUND
        WLCOUNT 1+!
      ELSE
        2DROP
      THEN WLALLWORDS 1+!
      CDR
    REPEAT R> WLADDREPORT
;

: WordsLike2Notepad ( -- )
    WLMaxNotepads? IF S" Открыть блокнот?" 5 0 TQUERY 0= IF EXIT THEN THEN
    S" notepad.exe" START-APP
    20 0 DO
      50 PAUSE
      NotepadTitle DROP Z" Notepad" FindWindowA ?DUP \ Проверку делаем в цикле для того чтобы пауза перед выводом текста была минимальная.
      IF
        WLWindowTitle2 >ZPAD WLFRAGMENT COUNT +ZPAD
        S"    "        +ZPAD WLFULLWORD @ N>S +ZPAD
        S"  / "        +ZPAD WLCOUNT @    N>S +ZPAD
        >R ZPAD R@ SetWindowTextA DROP \ Меняем заголовок чтобы при запуске нескольких блокнотов FindWindowA находила последний открытый блокнот.
        0 Z" Edit" 0 R> FindWindowExA >R
        WLFOUND SCOUNT DROP 0 12 R> SendMessageA DROP \ #define WM_SETTEXT 12
        LEAVE
      THEN
    LOOP
;

WINAPI: SetDlgItemTextA USER32.DLL

: WLSetButtonText ( -- )
    10 0 DO
      10 PAUSE
      WLWindowTitle1 DROP Z" #32770" FindWindowA ?DUP   \ Проверку делаем в цикле для того чтобы пауза перед выводом текста была минимальная.
      IF
        >R WLWindowTitle2 DROP R@ SetWindowTextA DROP \ Меняем заголовок чтобы при запуске нескольких задач FindWindowA находила последний открытый диалог.
        Z" Закрыть"    2 R@ SetDlgItemTextA DROP  \ #define IDCANCEL    2
        Z" Назад"     10 R@ SetDlgItemTextA DROP  \ #define IDTRYAGAIN 10
        Z" В блокнот" 11 R> SetDlgItemTextA DROP  \ #define IDCONTINUE 11
       LEAVE
      THEN
    LOOP
;

VECT WordsLikeInput

VARIABLE wlcloseall

\ Закрывает все окна открытые задачей, в том числе блокноты.
: WLWinCloseAll ( -- )
    wlcloseall @
    IF
      WLWindowTitle1 DROP Z" spfwinclass" WIN-NAME-CLOSE-ALL
      WLWindowTitle2 DROP Z" #32770" WIN-NAME-CLOSE-ALL
      ALL WIN-CLOSE: "%WLWindowTitle2%*" \ Блокноты
    THEN
;

: WordsLike2Messagebox ( -- )
    ['] WLSetButtonText EXECUTE-LAUNCH
    0x40106 WLWindowTitle1 DROP  \ MB_CANCELTRYCONTINUE+MB_DEFBUTTON2+MB_TOPMOST
\    WLFOUND SCOUNT DROP 0 MessageBoxA
    WLFOUND CELL+ 0 MessageBoxA
    CASE
      11  OF WordsLike2Notepad ENDOF \ Продолжить (В блокнот)
      10  OF WordsLikeInput ENDOF    \ Повторить  (Назад)
       2  OF WLWinCloseAll ENDOF     \ Отмена     (Закрыть)
      DUP OF NOOP ENDOF
    ENDCASE
;

: WLGetFragment ( a u -- )
    LTRIM                  \ Удаляем из начала пробелы, табуляции, переводы строк.
    CropAfterWord          \ Берем первое слово.
    60 MIN WLFRAGMENT PLACE0 \ Укорачиваем длинный фрагмент.

;


\ mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
fVAR wordslike_history \ Файловая переменная для хранения истории запросов.

: WLHistoryManage ( -- )
    WLFRAGMENT C@ 0= IF EXIT THEN
    WLFOUND 0!
    WLFRAGMENT COUNT +WLFOUND
    CRLF             +WLFOUND
    wordslike_history OVER >R
    FOR-LINES
      LINE-NUMBER wlmaxhistory = IF LINE-EXIT EXIT THEN    \ LINE-EXIT - выход из BEGIN    а EXIT - выход из [NONAME NONAME]
      FOUND-LINE WLFRAGMENT COUNT COMPARE
      IF FOUND-LINE +WLFOUND CRLF +WLFOUND ELSE LINE-NUMBER 1- TO LINE-NUMBER THEN
    ;FOR-LINES
    WLFOUND SCOUNT TO wordslike_history
    R> FREE DROP \ Если файла нет то FREE дает ошибку т.к. память не выделяется (см. слово fVAR).
;

\ -------------------- Меню --------------------
0 VALUE wlhwnd

\ Вставляет текст в поле ввода.
: WLSetInputText ( az -- )
    0 Z" Edit" 0 wlhwnd FindWindowExA >R
    0 12 R@ SendMessageA DROP \ #define WM_SETTEXT 12
    R> WinActivate End
;

: WLHistoryMenuBuild ( -- )
    POPUPMENU
      wordslike_history OVER >R
      FOR-LINES
        ZPAD FOUND-LINE 2DUP >ZPAD SWAP MENUITEM
      ;FOR-LINES
    END-MENU
    RunMenu
    IF MENUITEM-TEXT DROP WLSetInputText THEN
    R> FREE DROP
    0 TO wlhwnd
;

: WLHistoryMenuShow ( -- )
    ['] WLHistoryMenuBuild EXECUTE-LAUNCH
    BEGIN 100 PAUSE wlhwnd 0= UNTIL
;

: WLWinActive? ( a u -- ? )
    GetForegroundWindow DUP TO wlhwnd GET-WTEXT COMPARE 0=
;

\ Открывает меню с историей поиска, мышью на кнопке [развернуть] (9).
: WLHistoryMenuM ( -- )
    VK_LBUTTON KEY-PRESSED?
    IF
      WLWindowTitle1 WLWinActive?
      IF
        wlhwnd SEND-WM_NCHITTEST 9 = IF WLHistoryMenuShow THEN
      THEN
    THEN
;

\ Открывает меню с историей поиска, по горячей клавише (Стрелка вниз).
: WLHistoryMenuK ( -- )
    VK_DOWN KEY-PRESSED?
    IF
      WLWindowTitle1 WLWinActive?
      IF
        wlhwnd WIN-RECT DROP MOUSE-MOVE DROP \ Мышь в правый верхний угол окна.
        WLHistoryMenuShow
        VK_DOWN WAIT-KUP
      THEN
    THEN
;
\ mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm


: WordsLike ( a u -- )
    WLGetFragment
    100 Kb ALLOCATE THROW DUP >R TO WLFOUND \ При поиске через "Повторить", будет выделен новый буфер. Поэтому запоминаем адрес текущего буфера в >R чтобы освободить память.
    WLHistoryManage
    (WordsLike)
    WLCOUNT @ 50 < \ Если найдено 50 и больше слов то выводим список сразу в блокнот.
    IF WordsLike2Messagebox ELSE WordsLike2Notepad THEN
    500 PAUSE
    R> FREE THROW
;

: WLPromptText ( -- a u )
    CRLF S" Введите часть искомого слова" S+
    icase? IF S" Поиск без учета регистра" 2SWAP S+ THEN
;

:NONAME ( -- )
    WLWindowTitle1 WLPromptText
    WLFRAGMENT COUNT 0 WIN-INPUT-TEXT 0=
    IF
      WordsLike
    ELSE
      WLWinCloseAll
    THEN
; TO WordsLikeInput

\ Находит диалоговое окно WIN-INPUT-TEXT
: WLFindWinInput ( 0 | hwnd -- 0 | nexthwnd )
    >R WLWindowTitle1 DROP Z" spfwinclass" R> 0 FindWindowExA
;

\ Меняет текст приглашения в диалоговом окне WIN-INPUT-TEXT: при нажатии Shift
: WLSetPromptText ( -- ) { \ hwnd -- }
    WLWindowTitle1 WLWinActive? IFNOT EXIT THEN
    0 WLFindWinInput TO hwnd
    BEGIN hwnd WHILE
      0 Z" Static" 0 hwnd FindWindowExA >R
      WLPromptText DROP 0 12 R> SendMessageA DROP \ #define WM_SETTEXT 12
      hwnd WLFindWinInput TO hwnd
    REPEAT
;

\ Проверка и обработка нажатий хоткеев и хоткликов.
: (WLWatchHKey) ( -- ) { \ flagcase -- }
    500 PAUSE
    icase? TO flagcase \ Начальное состояние переключателя.
    BEGIN WLTaskCounter WHILE
      50 PAUSE
      icase? DUP flagcase <>
      IF DUP TO flagcase WLSetPromptText THEN DROP
      WLHistoryMenuK
      WLHistoryMenuM
      VK_SHIFT KEY-PRESSED? wlcloseall !
    REPEAT
;

: WLWatchHKey ( -- )
    CUR-NODE CRON-COUNTER @ 1 =  \ Если запущен первый экзепляр задачи.
    IF
       CUR-NODE TO <cron-node>
      ['] (WLWatchHKey) EXECUTE-LAUNCH
    THEN
;


: (WORDS~LIKE) ( -- )
    WLWatchHKey
    WLTaskCounter wlmaxcounter > IF EXIT THEN
    ENU LngActivate
    CLIPBOARD@ WLGetFragment
    WordsLikeInput
;


%>


#( CLASSIC-TASK-#-WORDSLIKE
\ NoActive
WatchHotKey: "$W" \ Win+W
CUR-NODE TO <cron-node>
Action:
    (WORDS~LIKE)
)#

#( CLASSIC-TASK-#-WORDSLIKE2
\ NoActive
SingleInstance
WatchHotKey: "$Q" \ Win+Q
Action:
    CLASSIC-TASK-#-WORDSLIKE LAUNCH
    VK_LWIN WAIT-KUP \ Можно подержать клавишу Win нажатой и переключить учет регистра (Shift), или закрыть окно, или деактивировать(мышкой или Win+(1-9) и т.п.).
    WLWindowTitle1 WLWinActive? IF Enter THEN
)#



<%
\ Для запуска из консоли.
\ : WORDS~LIKE ( -- )
\    CLASSIC-TASK-#-WORDSLIKE LAUNCH
\    100 PAUSE
\    0 WLFindWinInput
\    WinActivate
\ ;
%>



Подключить плагин extwords.spf
Подключить кронтаб nncron_extwords2.tab
Last edited by dothen on Sun, 07 May 2017, 17:03, edited 8 times in total.
dothen
 
Posts: 184
Joined: Mon, 16 Mar 2015, 04:58

Re: WORDS-LIKE поиск слов в словаре nnCron

Postby VoidVolker » Tue, 15 Mar 2016, 09:12

95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: WORDS-LIKE поиск слов в словаре nnCron

Postby Teapot » Sun, 20 Mar 2016, 21:24

Было бы здорово, если бы поиск велся без учета регистра букв.
Teapot
 
Posts: 3
Joined: Wed, 09 Dec 2015, 18:48

Re: WORDS-LIKE поиск слов в словаре nnCron

Postby dothen » Sun, 20 Mar 2016, 22:26

В слове words-like заменить слово SEARCH на ISEARCH
dothen
 
Posts: 184
Joined: Mon, 16 Mar 2015, 04:58

Re: Задача WORDS-LIKE поиск слов в словаре nnCron

Postby dothen » Sun, 04 Dec 2016, 03:56

Переделал задачу.
Подробности в описании.
dothen
 
Posts: 184
Joined: Mon, 16 Mar 2015, 04:58

Re: Задача WORDS-LIKE поиск слов в словаре nnCron

Postby dothen » Tue, 14 Feb 2017, 17:10

Добавлено:
История введенных слов.
Поиск с использованием регулярных выражений.
Закрытие всех окон поиска.

Другие изменения, исправления.
dothen
 
Posts: 184
Joined: Mon, 16 Mar 2015, 04:58

Re: Задача WORDS-LIKE поиск слов в словаре nnCron

Postby dothen » Tue, 28 Mar 2017, 21:54

Исправлена ошибка при поиске с регулярными выражениями (символ "/" проверялся только в начале).
Другие мелкие исправления.
dothen
 
Posts: 184
Joined: Mon, 16 Mar 2015, 04:58


Return to nnCron forum (Russian)

Who is online

Users browsing this forum: No registered users and 1 guest