Дом/клавиши End в zsh не работает со шпаклевкой

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

Помимо синтаксиса, довольно необычного и не очень идиоматического (вкус, конечно, дискуссионный), вам необязательно создавать две существенные проблемы в вашем приложении , о котором я только что недавно подробно рассказал здесь .

1. Вы создаете слишком много анонимных классов

Каждый раз, когда вы используете инициализацию двойной скобки, создается новый класс. Например. этот пример:

Map source = new HashMap(){{
    put("firstName", "John");
    put("lastName", "Smith");
    put("organizations", new HashMap(){{
        put("0", new HashMap(){{
            put("id", "1234");
        }});
        put("abc", new HashMap(){{
            put("id", "5678");
        }});
    }});
}};

... будет генерировать эти классы:

Test$1$1$1.class
Test$1$1$2.class
Test$1$1.class
Test$1.class
Test.class

Это довольно немного накладных расходов для вашего загрузчика классов - ни за что! Конечно, это не займет много времени для инициализации, если вы это сделаете один раз. Но если вы делаете это 20 000 раз по всему вашему корпоративному приложению ... все, что куча памяти только для немного «синтаксиса сахара»?

2. Вы потенциально создаете утечку памяти!

Если вы возьмете приведенный выше код и вернете эту карту из метода, вызывающие его методы могут ничего не подозревать на очень тяжелых ресурсах, которые не могут быть собраны в мусор. Рассмотрим следующий пример:

public class ReallyHeavyObject {

    // Just to illustrate...
    private int[] tonsOfValues;
    private Resource[] tonsOfResources;

    // This method almost does nothing
    public Map quickHarmlessMethod() {
        Map source = new HashMap(){{
            put("firstName", "John");
            put("lastName", "Smith");
            put("organizations", new HashMap(){{
                put("0", new HashMap(){{
                    put("id", "1234");
                }});
                put("abc", new HashMap(){{
                    put("id", "5678");
                }});
            }});
        }};

        return source;
    }
}

Возвращенный Map теперь будет содержать ссылку на экземпляр-экземпляр ReallyHeavyObject. Вероятно, вы не хотите рисковать этим:

Memory Leak Right Here [/g5]

Изображение из http://blog.jooq.org/2014/12/ 08 / dont-be-clever-the-double-curly-braces-anti-pattern /

3. Вы можете притворяться, что Java имеет литералы на карте

. Чтобы ответить на ваш реальный вопрос, люди использовали этот синтаксис, чтобы притворяться, что Java имеет что-то вроде картографических литералов, похожих на существующие литералы массивов:

String[] array = { "John", "Doe" };
Map map = new HashMap() {{ put("John", "Doe"); }};

Некоторые люди могут найти это синтаксически стимулирующее.

33
задан Myrddin Emrys 12 February 2010 в 00:24
поделиться

5 ответов

Я нашел, что это - комбинация:

Один

Разработчики ZSH не думают, что ZSH должен определить действия Дома, End, Делавэр... ключи.

Debian и Ubuntu фиксируют это путем определения нормальных действий, которые средний пользователь ожидал бы в глобальном /etc/zsh/zshrc файл. В соответствии с соответствующими нормами (это - то же на Debian и Ubuntu):

if [[ "$TERM" != emacs ]]; then
[[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char
[[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
[[ -z "$terminfo[kend]" ]] || bindkey -M emacs "$terminfo[kend]" end-of-line
[[ -z "$terminfo[kich1]" ]] || bindkey -M emacs "$terminfo[kich1]" overwrite-mode
[[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char
[[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line
[[ -z "$terminfo[kend]" ]] || bindkey -M vicmd "$terminfo[kend]" vi-end-of-line
[[ -z "$terminfo[kich1]" ]] || bindkey -M vicmd "$terminfo[kich1]" overwrite-mode

[[ -z "$terminfo[cuu1]" ]] || bindkey -M viins "$terminfo[cuu1]" vi-up-line-or-history
[[ -z "$terminfo[cuf1]" ]] || bindkey -M viins "$terminfo[cuf1]" vi-forward-char
[[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history
[[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history
[[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char
[[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char

# ncurses fogyatekos
[[ "$terminfo[kcuu1]" == "^[O"* ]] && bindkey -M viins "${terminfo[kcuu1]/O/[}" vi-up-line-or-history
[[ "$terminfo[kcud1]" == "^[O"* ]] && bindkey -M viins "${terminfo[kcud1]/O/[}" vi-down-line-or-history
[[ "$terminfo[kcuf1]" == "^[O"* ]] && bindkey -M viins "${terminfo[kcuf1]/O/[}" vi-forward-char
[[ "$terminfo[kcub1]" == "^[O"* ]] && bindkey -M viins "${terminfo[kcub1]/O/[}" vi-backward-char
[[ "$terminfo[khome]" == "^[O"* ]] && bindkey -M viins "${terminfo[khome]/O/[}" beginning-of-line
[[ "$terminfo[kend]" == "^[O"* ]] && bindkey -M viins "${terminfo[kend]/O/[}" end-of-line
[[ "$terminfo[khome]" == "^[O"* ]] && bindkey -M emacs "${terminfo[khome]/O/[}" beginning-of-line
[[ "$terminfo[kend]" == "^[O"* ]] && bindkey -M emacs "${terminfo[kend]/O/[}" end-of-line
fi

Так, если Вы соединяетесь с полем Debian или Ubuntu, Вы ничего не должны делать. Все должно работать автоволшебно (в противном случае посмотрите ниже).

Но... если Вы соединяетесь с другим полем (например, FreeBSD), не могло бы быть никакого удобного для пользователя значения по умолчанию zshrc. Решение состоит в том, чтобы, конечно, добавить строки от Debian/Ubuntu zshrc к Вашему собственному .zshrc.

Два

Шпаклевка отправляет xterm как терминал вводят к удаленному хосту. Но портит где-нибудь и не отправляет корректные коды управления за Домом, Концом... что можно было бы ожидать из xterm. Или xterm терминал, как ожидают, не отправит их или безотносительно... (Клавиша Del действительно работает в xterm однако, если Вы настраиваете его в ZSH). Также заметьте что Ваше действие Ключей цифровой клавиатуры, забавное в Vim, например, с xterm терминал.

Решение состоит в том, чтобы настроить Шпаклевку для отправки другого терминального типа. Я попробовал xterm-color и linux. xterm-color решенный проблема Дома/Конца, но Цифровая клавиатура была все еще забавна. Установка его к linux решенный обе проблемы.

Можно установить терминальный тип в Шпаклевке при Соединении-> Данные. Не испытывайте желание установить свой терминал, вводят Ваш .zshrc с export TERM=linux, это просто неправильно. Терминальный тип должен быть указан Вашим терминальным приложением. Так, чтобы, если, например, Вы соединяетесь от поля Mac с клиентом SSH Mac, оно могло установить свой собственный терминальный тип.

Заметьте, что ТЕРМИН указывает Ваш терминальный тип и не имеет никакого отношения к хосту, с которым Вы соединяетесь. Я могу установить свой терминальный тип на linux в Шпаклевке и подключении к серверам FreeBSD без проблем.

Так, почините и эти вещи, и необходимо быть в порядке :)

66
ответ дан 27 November 2019 в 17:39
поделиться

Эта привязка просто, кажется, не часть набора привязки по умолчанию в emacs режиме.

выполнение, "где - начало строки" на моем значении по умолчанию zsh установка после выполнения "bindkey-e", показывает, что только связывается с ^a. Возможно, необходимо спросить zsh разработчиков почему :-)

0
ответ дан 27 November 2019 в 17:39
поделиться

Это кажется вещью шпаклевки. Терминал Gnome отправляет коды ^[OH и ^[OF для Дома и Конца соответственно, в то время как шпаклевка отправляет ^[[1~ и ^[[4~. Существует опция в шпаклевке для изменения Дома/клавиш End от стандарт режим к режим rxvt , и это, кажется, фиксирует клавишу Home, но не клавишу End (который теперь отправляет ^[Ow). Угадайте, что пора зарегистрировать отчет об ошибках где-нибудь... :-)

3
ответ дан 27 November 2019 в 17:39
поделиться

Это теперь были почти 11 лет, с тех пор как этот вопрос был сначала отправлен. В то время некоторые дистрибутивы действительно поставлялись с putty terminfo запись, но это было посредственно в лучшем случае В годах с тех пор, ситуация улучшилась, и взломы, которые были необходимы больше десятилетия, больше не требуются. PuTTY все еще принимают значение по умолчанию к установке TERM к xterm для совместимости, но если Вы соединитесь с современными, актуальными системами, то у Вас, вероятно, будет удача при переопределении этого и установке ее на putty-256color:

  1. Гарантируют, что хост имеет terminfo запись для putty-256color: toe -a | grep -F putty
  2. Отмена любые взломы Вы, возможно, включили для получения PuTTY, работающего правильно с zsh или другими программами.
  3. Гарантируют, что PuTTY актуален. Это не уведомит Вас, когда обновления будут доступны, и если это является устаревшим, Вы, вероятно, собираетесь столкнуться с большим количеством тех же проблем. Можно хотеть усовершенствовать его автоматически чего-то как [1 121] Шоколадный .
  4. В диалоговом окне конфигурации PuTTY, перейдите к Соединению-> Данные и установите "Строку Терминального типа" на putty-256color.
  5. , В то время как Вы в нем на том же экране конфигурации, добавляет новая переменная среды для включения 24-разрядного цвета. Эта переменная не стандартизирована, но она отправляется многими другими основными эмуляторами терминала (например, iTerm2), и много программ понимают это.
    1. Переменная: COLORTERM
    2. Значение: truecolor
  6. На момент написания этих строк я не нашел дистрибутив, который принимает переменную COLORTERM по SSH по умолчанию. Необходимо будет отредактировать конфигурацию OpenSSH на хосте для разрешения его. Например, на подобных Debian дистрибутивах, отредактируйте /etc/ssh/sshd_config и добавьте COLORTERM к AcceptEnv строка.
  7. Все должно теперь "просто работать". Если это не делает:
    1. Гарантируют, что Вы снова соединились после внесения изменения или по крайней мере работали exec zsh за изменением TERM. zsh не будет реагировать на изменения в [1 114], в то время как он работает.
    2. Гарантируют, что TERM на самом деле установлен на то, что Вы предназначили: echo $TERM
    3. Вы на последней версии Вашего дистрибутива? Если Вы находитесь на сборке жизненного цикла долговременной поддержки, например, даже если Ваша версия технически все еще поддерживается, она не может иметь актуальных terminfo записей.
    4. Вы использующий screen или tmux? Это - другая целая куча проблем. Тест без тех сначала для сужения, где проблема происходит. В tmux попробуйте установку TERM=tmux-256color. В экране попробуйте TERM=screen-256color.
    5. Вы на последней версии PuTTY?
    6. у Вас есть файлы RC, которые реализуют привязки клавиш или другие взломы? Попытайтесь использовать файлы RC по умолчанию.
    7. Вы уже изменили различные настройки PuTTY, чтобы попытаться устранить проблему прежде, чем попытаться, terminfo фиксируют? Необходимо будет, вероятно, сбросить те настройки.
0
ответ дан 27 November 2019 в 17:39
поделиться

В диалоговом окне конфигурации PuTTY перейдите в меню «Соединение» -> «Данные» и введите linux в строку типа терминала перед подключением.

16
ответ дан 27 November 2019 в 17:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: