Режим Comint вставляет разрыв строки через каждые 4096 символов - PullRequest
3 голосов
/ 04 апреля 2011

Используя Emacs 23.2.1 в Ubuntu Lucid, любой режим, основанный на Comint, вставляет случайные разрывы строк для больших выходных данных (см. Пример вывода в режиме Shell и SQL ниже). Я пробовал это и в режиме SQL, и в режиме оболочки, с одинаковым результатом в любом случае. Выполнение аналогичных команд в простом эмуляторе терминала не вызывает этих проблем (как для команд режима shell, так и для команд режима mysql).

Вещи, которые я пробовал:

  • Использование MySQL в режиме SQL, добавление следующих флагов: -A, -C, -t, -f, -n и установка max_allowed_packet в 16 МБ.

  • Установка максимального размера comint-buffer на 10240.

Ничто из этого не влияет на это поведение.

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

Примечание: в примерах терминала вывод обрезается в точках, отличных от каждых 4096 символов. В режиме SQL это точно каждые 4096 (действительно подозрительное число).

Вот пример вывода:

brent@battlecruiser:/$ for i in {1..4096}; do echo -n 0; done; echo;

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

В этом случае он должен распечатать одну строку из 0 с, но фактически вставил новый символ строки после 904 символов.

Также пример в режиме SQL с использованием MySQL:

mysql> show variables like '%n%';

+-----------------------------------------+----------------------------------+
| Variable_name                           | Value                            |
+-----------------------------------------+----------------------------------+
| auto_increment_increment                | 1                                |
| auto_increment_offset                   | 1                                |
| binlog_cache_size                       | 32768                            |
| binlog_format                           | STATEMENT                        |
| bulk_insert_buffer_size                 | 8388608                          |
| character_set_client                    | utf8                             |
| character_set_connection                | utf8                             |
| collation_connection                    | utf8_general_ci                  |
| collation_database                      | latin1_swedish_ci                |
| collation_server                        | latin1_swedish_ci                |
| completion_type                         | 0                                |
| concurrent_insert                       | 1                                |
| connect_timeout                         | 10                               |
| delayed_insert_limit                    | 100                              |
| delayed_insert_timeout                  | 300                              |
| div_precision_increment                 | 4                                |
| engine_condition_pushdown               | ON                               |
| error_count                             | 0                                |
| event_scheduler                         | OFF                              |
| foreign_key_checks                      | ON                               |
| ft_boolean_syntax                       | + -><()~*:""&|                   |
| ft_max_word_len                         | 84                               |
| ft_min_word_len                         | 4                                |
| ft_query_expansion_limit                | 20                               |
| general_log                             | OFF                              |
| general_log_file                        | /var/lib/mysql/battlecruiser.log |
| group_concat_max_len                    | 1024                             |
| have_community_features                 | YES                              |
| have_dynamic_loading                    | YES                              |
| have_innodb                             | YES                              |
| have_ndbcluster                         | NO                               |
| have_openssl                            | DISABLED                         |
| have_partitioning                       | YES                              |
| have_symlink                            | YES                              |
| hostname                                | battlecruiser                    |
| identity                                | 0                                |
| ignore_builtin_innodb                   | OFF                              |
| init_connect                            |                                  |
| init_file                               |                                  |
| init_slave                              |                                  |
| innodb_adaptive_hash_index              | ON                               |
| innodb_additional_mem_pool_size         | 1048576                          |
| innodb_autoextend_increment             | 8                                |
| innodb_autoinc_lock_mode                | 1                                |
| innodb_buffer_pool_size                 | 8388608                          |
| innodb_checksums                        | ON                               |
| innodb_commit_concurrency               | 0                                |
| innodb_concurrency_tickets              | 500                              |
| innodb_data_file_path                   | ibdata1:10M:autoextend
           |
| innodb_data_home_dir                    |                                  |
| innodb_doublewrite                      | ON                               |
| innodb_fast_shutdown                    | 1                                |
| innodb_file_io_threads                  | 4                                |
| innodb_file_per_table                   | OFF                              |
| innodb_flush_log_at_trx_commit          | 1                                |
| innodb_flush_method                     |                                  |
| innodb_force_recovery                   | 0                                |
| innodb_lock_wait_timeout                | 50                               |
| innodb_locks_unsafe_for_binlog          | OFF                              |
| innodb_log_buffer_size                  | 1048576                          |
| innodb_log_file_size                    | 5242880                          |
| innodb_log_files_in_group               | 2                                |
| innodb_log_group_home_dir               | ./                               |
| innodb_max_dirty_pages_pct              | 90                               |
| innodb_max_purge_lag                    | 0                                |
| innodb_mirrored_log_groups              | 1                                |
| innodb_open_files                       | 300                              |
| innodb_rollback_on_timeout              | OFF                              |
| innodb_stats_on_metadata                | ON                               |
| innodb_support_xa                       | ON                               |
| innodb_sync_spin_loops                  | 20                               |
| innodb_table_locks                      | ON                               |
| innodb_thread_concurrency               | 8                                |
| innodb_thread_sleep_delay               | 10000                            |
| innodb_use_legacy_cardinality_algorithm | ON                               |
| insert_id                               | 0                                |
| interactive_timeout                     | 28800                            |
| join_buffer_size                        | 131072                           |
| keep_files_on_create                    | OFF                              |
| key_cache_division_limit                | 100                              |
| language                                | /usr/share/mysql/english/        |
| last_insert_id                          | 0                                |
| lc_time_names                           | en_US                            |
| license                                 | GPL                              |
| local_infile                            | ON                               |
| locked_in_memory                        | OFF                              |
| log_bin                                 | OFF                              |
| log_bin_trust_function_creators         | OFF                              |
| log_bin_trust_routine_creators          | OFF                              |
| log_queries_not_using_indexes           | OFF                              |
| log_warnings                            | 1                                |
| long_query_time                         | 10.000000                        |
| lower_case_table_names                  | 0                                |
| max_binlog_cache_size                   | 4294963200                       |
| max_binlog_size                         | 104857600                        |
| max_connect_errors                      | 10                               |
| max_connections                         | 151                              |
| max_error_count                         | 64                               |
| max_insert_delayed_threads              | 20                               |
| max_join_size                           | 18446744073709551615             |
| max_length_for_sort_data                | 1024     
                        |
| max_prepared_stmt_count                 | 16382                            |
| max_sort_length                         | 1024                             |
| max_sp_recursion_depth                  | 0                                |
| max_user_connections                    | 0                                |
| max_write_lock_count                    | 4294967295                       |
| min_examined_row_limit                  | 0                                |
| multi_range_count                       | 256                              |
| myisam_data_pointer_size                | 6                                |
| myisam_recover_options                  | BACKUP                           |
| net_buffer_length                       | 16384                            |
| net_read_timeout                        | 30                               |
| net_retry_count                         | 10                               |
| net_write_timeout                       | 60                               |
| new                                     | OFF                              |
| open_files_limit                        | 1024                             |
| optimizer_prune_level                   | 1                                |
| plugin_dir                              | /usr/lib/mysql/plugin            |
| profiling                               | OFF                              |
| profiling_history_size                  | 15                               |
| protocol_version                        | 10                               |
| query_cache_min_res_unit                | 4096                             |
| query_cache_wlock_invalidate            | OFF                              |
| rand_seed1                              |                                  |
| rand_seed2                              |                                  |
| range_alloc_block_size                  | 4096                             |
| read_only                               | OFF                              |
| read_rnd_buffer_size                    | 262144                           |
| relay_log_index                         |                                  |
| relay_log_info_file                     | relay-log.info                   |
| rpl_recovery_rank                       | 0                                |
| skip_external_locking                   | ON                               |
| skip_networking                         | OFF                              |
| slave_net_timeout                       | 3600                             |
| slave_transaction_retries               | 10                               |
| slow_launch_time                        | 2                                |
| sql_auto_is_null                        | ON                               |
| sql_log_bin                             | ON                               |
| sql_max_join_size                       | 18446744073709551615             |
| sql_notes                               | ON                               |
| sql_slave_skip_counter                  |                                  |
| sql_warnings                            | OFF                              |
| storage_engine                          | MyISAM                           |
| sync_binlog                             | 0                                |
| sync_frm                                | ON                               |
| system_time_zone                        | EDT                              |
| table_definition_cache                  | 256                              |
| table_open_cache                        | 64                               |
| thread_handling                         | one-thread-per-connection        |
| time_zone                               | SYSTEM                           |
| transaction_alloc_block_size            | 8192                             |
| transaction_prealloc_size               | 4096                             |
| tx_isolation                          
  | REPEATABLE-READ                  |
| unique_checks                           | ON                               |
| version                                 | 5.1.41-3ubuntu12.10              |
| version_comment                         | (Ubuntu)                         |
| version_compile_machine                 | i486                             |
| version_compile_os                      | debian-linux-gnu                 |
| warning_count                           | 0                                |
+-----------------------------------------+----------------------------------+
159 rows in set (0.00 sec)

Здесь вывод всегда прерывается новой строкой с точным интервалом в 4096 символов.

В дополнение к возможным решениям будут приветствоваться любые новые способы получения дополнительной информации о происходящем.

Ответы [ 4 ]

4 голосов
/ 04 апреля 2011

У меня были похожие проблемы, хотя мои разрывы, похоже, были в 1024 символах ( ах-ха! в версии 21_1 это было так).Это было не так уж важно для меня, но я написал что-то, что правильно связало результаты, чтобы я мог обработать их.Это не повлияло на вывод, так что это не сильно поможет.

Корень вашей проблемы лежит в read_process_output в process.c , который жестко кодирует 4096:

/* Read pending output from the process channel,
   starting with our buffered-ahead character if we have one.
   Yield number of decoded characters read.

   This function reads at most 4096 characters.
   If you want to read all available subprocess output,
   you must call it repeatedly until it returns zero.

   The characters read are decoded according to PROC's coding-system
   for decoding.  */

static int
read_process_output (proc, channel)
     Lisp_Object proc;
     register int channel;
{
  // ... snip
  int readmax = 4096;

Как вы упомянули в своем вопросе, очень возможным решением этой проблемы было бы написать функцию (вызвать ее, clean-up-comint-output-at-4096-chars) и добавить ее к comint-output-filter-functions.Что-то вроде этого. Примечание: непроверенный код .

(add-hook 'comint-output-filter-functions 'clean-up-comint-output-at-4096-chars)
(defun clean-up-comint-output-at-4096-chars (&optional str)
  "look for string of 4096 length and remove newline in the buffer"
  (let ((magic-block-size 4096))
    (save-match-data
      (when (= magic-block-size (length str))
        ;; at the magic block size, look for a newline
        (goto-char (point-max))
        (when (and (search-backward str nil t)
                   (progn
                     (forward-char magic-block-size)
                     (looking-at "\n")))
          (delete-char 1))))))
3 голосов
/ 06 апреля 2011

Я нашел решение этой проблемы.Я поместил в свой файл конфигурации следующий код, полученный из http://www.emacswiki.org/emacs/SqlMode

  (defun sql-add-newline-first (output)
    "Add newline to beginning of OUTPUT for `comint-preoutput-filter-functions'"
    (concat "\n" output))

  (defun sqli-add-hooks ()
    "Add hooks to `sql-interactive-mode-hook'."
    (add-hook 'comint-preoutput-filter-functions
              'sql-add-newline-first))

  (add-hook 'sql-interactive-mode-hook 'sqli-add-hooks)

После удаления кода (который, поскольку он устанавливает comint-preoutput-filter-functions, также влияет на shell-mode), я больше не испытываюэти проблемы.

Моя предложенная замена для этого кода, чтобы получить поведение, которое я хочу (работает для меня до сих пор):

(defun sql-add-newline-first (output)
  "Add newline to beginning of OUTPUT for `comint-preoutput-filter-functions'"
  (remove-hook 'comint-preoutput-filter-functions
           'sql-add-newline-first)
  (concat "\n" output))

(defun sql-send-region-better (start end)
  "Send a region to the SQL process."
  (interactive "r")
  (if (buffer-live-p sql-buffer)
      (save-excursion
    (add-hook 'comint-preoutput-filter-functions
          'sql-add-newline-first)
    (comint-send-region sql-buffer start end)
    (if (string-match "\n$" (buffer-substring start end))
        ()
      (comint-send-string sql-buffer "\n"))
    (message "Sent string to buffer %s." (buffer-name sql-buffer))
    (if sql-pop-to-buffer-after-send-region
        (pop-to-buffer sql-buffer)
      (display-buffer sql-buffer)))
    (message "No SQL process started.")))

(defvar sql-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "C-c C-c") 'sql-send-paragraph)
    (define-key map (kbd "C-c C-r") 'sql-send-region-better)
    (define-key map (kbd "C-c C-s") 'sql-send-string)
    (define-key map (kbd "C-c C-b") 'sql-send-buffer)
    map)
  "Mode map used for `sql-mode'.")

По сути, я добавляю хук прямо перед моим sql-Код send-region-better начинает отправлять вывод, затем внутри хука Я снова удаляю хук, гарантируя, что он вставит только одну новую строку, которую я хочу.

1 голос
/ 30 марта 2013

Вот моя реализация только добавление "\ n" один раз для каждого ввода:

(defvar sql-last-prompt-pos 1
  "position of last prompt when added recording started")
(make-variable-buffer-local 'sql-last-prompt-pos)
(put 'sql-last-prompt-pos 'permanent-local t)



(defun sql-add-newline-first (output)
  "Add newline to beginning of OUTPUT for
  `comint-preoutput-filter-functions'

  This fixes up the display of queries sent to the inferior
  buffer programatically.  But also adds extra new-line for
  interactive commands.

  "
  (let ((begin-of-prompt
         (or (and comint-last-prompt-overlay
                  ;; sometimes this overlay is not on prompt
                  (save-excursion
                    (goto-char (overlay-start comint-last-prompt-overlay))
                    (looking-at-p comint-prompt-regexp)
                    (point)))
             1)))
    (if (> begin-of-prompt sql-last-prompt-pos)
        (progn
          (setq sql-last-prompt-pos begin-of-prompt)
          (concat "\n" output))
      output)))

(defun le-sqli-setup ()
  "Add hooks to `sql-interactive-mode-hook'."
  (add-hook 'comint-preoutput-filter-functions
            'sql-add-newline-first t t))
(add-hook 'sql-interactive-mode-hook 'le-sqli-setup)
0 голосов
/ 05 апреля 2013

Мое решение - добавить новую строку (но затем убрать зацепку, чтобы несколько текстов не разбились).А затем повторно добавляйте ловушку при каждом запросе ввода.

(defun sql-add-newline-first (output)
    "Add newline to beginning of sql OUTPUT, but remove the hook so
     that it doesn't output a newline everytime the output cache is
     filled."
    (remove-hook 'comint-preoutput-filter-functions 'sql-add-newline-first)
    (concat "\n" output))

(defun sql-readd-newline-first (ignore)
  "Readd the newline putting hook"
  (add-hook 'comint-preoutput-filter-functions 'sql-add-newline-first))

(defun sqli-add-hooks ()
  "Add the 'suicidal' newline printing hook, and another hook to
   respawn it at every input prompt."
  (add-hook 'comint-preoutput-filter-functions 'sql-add-newline-first)
  (add-hook 'comint-input-filter-functions 'sql-readd-newline-first))

(add-hook 'sql-interactive-mode-hook 'sqli-add-hooks)

Кроме того, в моем случае я использовал postgresql.Который имеет неприятную привычку ставить дополнительные запросы после многострочного запроса (например, database- # database- # database- # | col | col |), который отталкивает имена столбцов.Чтобы решить, я в итоге сделал это:

(defun sql-remove-continuing-prompts (output)
  (concat "\n" (replace-regexp-in-string "warren_hero[^=()]# " "" output)))

(defun sqli-add-hooks ()
  (add-hook 'comint-preoutput-filter-functions 'sql-remove-continuing-prompts))

(add-hook 'sql-interactive-mode-hook 'sqli-add-hooks)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...