+0 000-000-00-00

Замена xneur для новых версий линукс

В связи с прекращением поддержки новых версий ubuntu клавиатурным менеджером xneur, он был заменен на 2 других скрипта

1. Замена сокращений (и много другое, чего не было в xneur) - Espanso

Установка описана тут

2. Конвертация последнего слова или фразы в другую раскладку - Easy Switcher (обсуждение на форуме

Фраза меняется по shift-PauseBreak, последнее слово - по PauseBreak..

После установки нужно поправить конфигурационный файл

sudo nano /etc/easy-switcher/default.cfg

 обычно нужно поправить сочетание клавиш, которые переключают раскладку. А также поправить delay 

Устанавливается как сервис, поэтому для запуска, после именения и для рестарта запускаем команды

sudo systemctl start easy-switcher
sudo systemctl stop easy-switcher

sudo systemctl restart easy-switcher

Проверка 

$ systemctl status easy-switcher
● easy-switcher.service - Easy Switcher - keyboard layout switcher
     Loaded: loaded (/usr/lib/systemd/system/easy-switcher.service; enabled; preset: enabled)
     Active: active (running) since Thu 2026-03-19 16:42:55 MSK; 46min ago
   Main PID: 37477 (easy-switcher)
      Tasks: 2 (limit: 27191)
     Memory: 612.0K (peak: 1.3M)
        CPU: 2.551s
     CGroup: /system.slice/easy-switcher.service
             └─37477 /usr/bin/easy-switcher -r

мар 19 16:42:55 boss systemd[1]: Started easy-switcher.service - Easy Switcher - keyboard layout switcher.
мар 19 16:42:55 boss easy-switcher[37477]: [Info] Starting Easy Switcher v0.4...
мар 19 16:42:55 boss easy-switcher[37477]: [Info] Easy Switcher started successfully.

Изменение раскладки выделенного текста

Эту задачу можно решить 2 способами. 

1. Триггер в Espanso

  - trigger: ":sw"
    replace: "{{output}}"
    vars:
      - name: clipboard
        type: clipboard
      - name: output
        type: shell
        params:
          cmd: |
            echo "{{clipboard}}" | sed "y/qwertyuiop[]asdfghjkl;'zxcvbnm,.\/QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?йцукенгшщзхъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,/йцукенгшщзхъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,qwertyuiop[]asdfghjkl;'zxcvbnm,.\/QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?/"

Как это работает:

  • Вы выделяете текст (мышкой или клавишами).
  • Нажимаете Ctrl+C (копируете).
  • Печатаете триггер :sw (от switch).
  • Espanso подставляет на место триггера текст из буфера, уже сконвертированный в другую раскладку.

Нет конфликтов с физическими клавишами: Espanso срабатывает после ввода текстового триггера, а не по «горячей клавише», поэтому система не «глючит» от одновременных нажатий.

Надежность: Espanso сам следит за тем, чтобы текст вставился целиком, не теряя первые символы.

Кросс-платформенность: Если вы перенесете конфиг на другой компьютер, он будет работать так же.

Можно ли сделать это «в одно нажатие»?

К сожалению, Espanso — это расширитель текстовых сокращений, а не глобальный обработчик горячих клавиш. Он не умеет сам нажимать Ctrl+C за вас.

Алгоритм всегда будет таким:

  • Выделили.
  • Ctrl+C.
  • Ввели :sw.

2. Простой скрипт на python

Чтобы сделать это без использования буфера обмена и решить проблему со скоростью (когда вставка не успевает за копированием), нужно использовать механизм X11 Primary Selection (это то, что попадает в память системы сразу при выделении мышкой, без нажатия Ctrl+C).

Решение через "Primary Selection" (без затирания буфера)

Этот скрипт берет текст напрямую из выделения, конвертирует его и «печатает» вместо выделенного текста, не трогая ваш буфер обмена (то, что вы копировали через Ctrl+C).

Установите зависимости (если еще нет):

sudo apt install xkblayout-state xdotool xclip

Создайте скрипт ~/Programs/switcher.py:

import subprocess
import time

def get_selected_text():
    # Берем текст напрямую из выделения (не из буфера обмена!)
    try:
        return subprocess.check_output(['xclip', '-o', '-selection', 'primary'], encoding='utf-8')
    except:
        return ""

def switch_layout():
    text = get_selected_text()
    if not text:
        return

    en_chars = "qwertyuiop[]asdfghjkl;'zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?@#$^&"
    ru_chars = "йцукенгшщзхъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,\"№;:?"

    # Создаем таблицу перевода в обе стороны
    to_ru = str.maketrans(en_chars, ru_chars)
    to_en = str.maketrans(ru_chars, en_chars)

    # Определяем, в какую сторону переводить (по первому найденному символу)
    first_char = next((c for c in text if c in en_chars or c in ru_chars), None)
    if not first_char:
        return
        
    converted = text.translate(to_ru) if first_char in en_chars else text.translate(to_en)

    # 1. Удаляем выделенный текст
    subprocess.run(['xdotool', 'key', 'BackSpace'])
    
    # 2. Печатаем новый текст напрямую (очень быстро)
    # Используем --clearmodifiers, чтобы зажатые клавиши (типа Alt) не мешали
    subprocess.run(['xdotool', 'type', '--clearmodifiers', converted])

    # 3. Опционально: переключаем раскладку в системе
    subprocess.run(['xdotool', 'key', 'alt+shift']) # Замените на ваш хоткей

if __name__ == "__main__":
    switch_layout()

В чем преимущества этого метода:

  • Ваш буфер (Ctrl+C) остается нетронутым.
  • Мгновенная работа: xdotool type имитирует ввод текста, что надежнее вставки из буфера.
  • Не нужно ждать: Мы не ждем, пока сработает системное копирование.

Как это использовать в Linux Mint:

  • chmod +x ~/Programs/switcher.sh
  • Зайдите в Параметры -> Клавиатура -> Комбинации клавиш.
  • Добавьте «Дополнительную команду».
  • Команда: python3 ~/Programs/switch_fast.py
  • Назначьте на клавишу (например, Shift-ScrollLock).

Важно: Чтобы этот скрипт работал, текст должен быть выделен мышкой. Если вы выделили текст клавиатурой (Shift + стрелки), он может не попасть в primary selection в некоторых приложениях.

В таком варианте скрипт работает очень медленно, потому что скрипт выше делает посимвольную замену. чтобы ускорить работу была изменена логика - выделение конвертуруется целиком. Код такой 
 

#!/usr/bin/env python3
import subprocess
import time

en_chars = "qwertyuiop[]asdfghjkl;'zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?`~@#$^&"
ru_chars = "йцукенгшщзхъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,ёЁ\"№;:?"

def get_clipboard():
    try:
        return subprocess.check_output(['xclip', '-o', '-selection', 'clipboard'], stderr=subprocess.DEVNULL)
    except:
        return b""

def set_clipboard(text_bytes):
    p = subprocess.Popen(['xclip', '-selection', 'clipboard'], stdin=subprocess.PIPE)
    p.communicate(input=text_bytes)

def main():
    # 1. Берем выделение (Primary не попадает в историю)
    try:
        selection = subprocess.check_output(['xclip', '-o', '-selection', 'primary'], encoding='utf-8')
    except:
        return
    if not selection:
        return

    # 2. Сохраняем то, что БЫЛО в буфере обмена (чтобы вернуть потом)
    old_clip = get_clipboard()

    # 3. Конвертируем
    result = []
    for char in selection:
        if char in en_chars:
            result.append(ru_chars[en_chars.index(char)])
        elif char in ru_chars:
            result.append(en_chars[ru_chars.index(char)])
        else:
            result.append(char)
    converted_text = "".join(result)

    # 4. Операция "Вспышка"
    # Помещаем текст в буфер
    set_clipboard(converted_text.encode('utf-8'))
    
    # Ждем микроскопическое время, чтобы X11 осознал наличие текста
    time.sleep(0.05)
    
    # Вставляем
    subprocess.run(['xdotool', 'key', 'ctrl+v'])
    
    # СРАЗУ возвращаем старое значение в буфер. 
    # Parcellite либо увидит старое значение, либо заменит новую запись старой.
    time.sleep(0.05)
    set_clipboard(old_clip)

if __name__ == "__main__":
    main()

Комментарии от Gemini:

Это происходит потому, что Parcellite (и аналогичные менеджеры в GTK) использует механизм «демона», который подписывается на события X11 SelectionNotify. Когда мы «размораживаем» его через CONT, он первым же делом проверяет текущее состояние буфера и, видя там новый текст, услужливо заносит его в историю.

Чтобы обойти это, нужно использовать метод подмены. Мы заставим скрипт работать так:

  1. Сохранить текущую историю (или последний элемент).
  2. Выполнить замену.
  3. Вернуть старый элемент на место, чтобы Parcellite подумал, что ничего не изменилось.

Однако есть еще более элегантный способ: использовать инструмент dotool или xdotool для вставки через «симуляцию клавиатуры», но не посимвольно (что медленно), а через техническую вставку из специального буфера, который Parcellite не слушает.

Но раз нам нужна скорость и невидимость, давайте используем «метод быстрого затирания».

Этот скрипт использует xclip для вставки, но сразу после команды «Вставить» (Ctrl+V) он очищает буфер или возвращает туда предыдущее значение настолько быстро, что Parcellite либо не успеет среагировать, либо перезапишет историю старым значением.

Комбинация сохранения старого буфера и его мгновенного возврата — это самый эффективный способ обмануть менеджеры буфера обмена, не прибегая к сложным системным манипуляциям. Parcellite просто не успевает или не считает нужным сохранять промежуточное состояние, так как оно подменяется почти мгновенно.

Parcellite работает по принципу «кто последний, тот и в истории».

  1. Скрипт записывает «привет».
  2. Скрипт нажимает Ctrl+V.
  3. Через 50 миллисекунд скрипт записывает обратно «то, что было до этого» (например, старую ссылку или текст).

Parcellite видит два события изменения. В итоге в топе его истории окажется старый текст, а исправленный «привет» либо вообще не успеет проиндексироваться, либо будет мгновенно вытеснен.

Пара финальных советов:

Скорость: Если заметите, что в некоторых тяжелых приложениях (вроде браузеров с кучей вкладок) текст иногда не успевает вставиться, увеличьте первую задержку time.sleep(0.05) до 0.1.

Символы: Теперь, когда логика идеальна, вы можете добавлять любые пары символов в en_chars и ru_chars, если встретите специфические раскладки (например, для программирования или математических знаков). Главное — сохранять их порядковое соответствие.

Посимвольную конвертацию оставил на всякий случай, а второй вариант скрипта повесил на F12.

Привязка к сочетаниям клавиш - через системные параметры клавиатуры Cinnamon "Параметры-Клавиатура-Быстрые команды-Дополнительные комбинации клавиш" 

    Опубликовано

    Menu