LINUX.ORG.RU

[emacs] косметический дефект sql-mode

 


0

0

При выполнении, например, sql-send-buffer, в буфере *SQL* отображается результат:

sqlite> sqlite> 19|name1|2000
20|name2|9999

Как сделать, чтобы вывод делался с новой строки? То есть так:

sqlite> sqlite> 
19|name1|2000
20|name2|9999

P. S. Emacs запущен в Cygwin, мне так удобнее. Про «родной» порт emacs для оффтопика знаю.



Последнее исправление: ipc (всего исправлений: 2)

Сам этим режимом не пользуюсь и не пользовался никогда, но ответ тебе нашел за 1 мин. на emacswiki. Проверяй.

When using sql-send-region to execute a query in a SQLi buffer, the table formatting is off because the column names are printed on the same row as the the prompt. By adding a newline before the comint output we can make sure everything lines up nice. This will add a preceding newline to every comint output, even queries run at the prompt - though the extra line isn’t too noticeable.

  (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)
Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Проверяй

Все ОК, но небольшой минус: если вводить запросы/команды sqlite непосредственно в буфере *SQL*, перевод строки все равно будет добавляться. Лишний:

sqlite> .tables

Table1  Table2  Table3
sqlite> 

Попытался исправить:

(setq need-newline 'nil)

(defun sql-add-newline-first (output) 
  "Add newline to beginning of OUTPUT for `comint-preoutput-filter-functions'" 
  (if need-newline
      (concat "\n" output)
    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) 

defadvice sql-send-buffer (before output-newline-on (&optional arg))
  (setq need-newline t))

(defadvice sql-send-buffer (after output-newline-off (&optional arg))
  (setq need-newline nil))

(ad-enable-advice 'sql-send-buffer 'before 'output-newline-on)
(ad-enable-advice 'sql-send-buffer 'after 'output-newline-off)
;;(ad-disable-advice 'sql-send-buffer 'after 'output-newline-off)
(ad-activate 'sql-send-buffer)
В общем, перед вызовом sql-send-buffer включаю флаг «вывод \n нужен», после - отключаю advice'ми. При вводе непосредственно в *SQL* функция sql-send-buffer не вызывается, флаг отключен, перевода строки выводиться не должно.

Не работает. Можете подсказать, в чем дело?

ipc
() автор топика
Ответ на: комментарий от ipc

>Не работает. Можете подсказать, в чем дело?

Первое, что приходит на ум: может, просто попробовать выдавать или не выдавать перевод строки по значению текущего буфера? Есть переменная sql-buffer, с которой можно сравнить имя текущего буфера. Если совпадет, то не выдавать перевод строки. По умолчанию и если буфер один, то значение его будет *SQL*. Хотя его можно переименовать и также много сессий одновременно иметь.

Zubok ★★★★★
()
Ответ на: комментарий от ipc

>В общем, перед вызовом sql-send-buffer включаю флаг «вывод \n нужен», после - отключаю advice'ми.

А ты уверен, что вызывается sql-send-buffer, а не sql-send-region или sql-send-string?

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Первое, что приходит на ум: может, просто попробовать выдавать или не выдавать перевод строки по значению текущего буфера?

Если такую проверку делать в sql-add-newline-first (см. выше), то значение будет всегда #<buffer *SQL*> (ну это понятно).
Если делать в advice output-newline-test, который вызывается перед sql-send-buffer:

(setq need-newline 'nil)

(defun sql-add-newline-first (output) 
  "Add newline to beginning of OUTPUT for `comint-preoutput-filter-functions'" 
  (if need-newline
      (progn
	(message "\n appended")
	(concat "\n" output))
    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) 

;;  (defadvice sql-send-buffer (before output-newline-on (&optional arg))
;;    (setq need-newline t))

(defadvice sql-send-buffer (after output-newline-off (&optional arg))
   (setq need-newline 'nil))

(defadvice sql-send-buffer (before output-newline-test (&optional arg))
  (setq need-newline (not (string= (buffer-name sql-buffer) (buffer-name))))
  (if need-newline 
      (message (concat "on " (buffer-name)))
    (message (concat "off " (buffer-name)))))

(ad-enable-advice 'sql-send-buffer 'before 'output-newline-test)
;; (ad-enable-advice 'sql-send-buffer 'before 'output-newline-on)
(ad-enable-advice 'sql-send-buffer 'after 'output-newline-off)
;;(ad-disable-advice 'sql-send-buffer 'after 'output-newline-off)
;;(ad-disable-advice 'sql-send-buffer 'before 'output-newline-on)
(ad-activate 'sql-send-buffer)
То есть перед вызовом sql-send-buffer advice'ом проверяется имя текущего буфера, если это не *SQL* - флаг перевод-строки-нужен устанавливается в t и наоборот. После вызова другим advice'ом флаг отключается т. е. все возвращается «как было».

Все равно не работает, в *Messages*:
on tt
Sent string to buffer *SQL*.
Вместо ожидаемого
on tt
\n appended
Sent string to buffer *SQL*.

А ты уверен, что вызывается sql-send-buffer, а не sql-send-region или sql-send-string?

Да, вызываю именно эту функцию комбинацией клавиш C-c C-b.

ipc
() автор топика
Ответ на: комментарий от ipc

Так нет же. Попробуй буфер проверять прямо в функции sql-add-newline-first. Забудь про defadvice.

(defun sql-add-newline-first (output) 
    "Add newline to beginning of OUTPUT for `comint-preoutput-filter-functions'" 
   (if (string= (buffer-name sql-buffer) (buffer-name)
и. т. д. ))

 
  (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) 
Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Хотя... есть предположение, что в момент срабатывания хука, буфер *SQL* всегда текущий. Если так, то надо бы подумать.

Zubok ★★★★★
()
Ответ на: комментарий от ipc

Если все это не получится, то просто определи свою функцию типа sql-my-send-buffer, навесь ее на комбинацию твою, а в функции sql-send-buffer оберни установкой твоего флага, который в (defvar sql-need-newline nil) определи. Может, и получится.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Лучше позже, чем никогда.

(defun my-sql-send-buffer ()
  (interactive)
  (let ((curr-buff (buffer-name))
	     (buff-text (buffer-substring-no-properties (point-min) (point-max))))
    (switch-to-buffer "*SQL*")
    (end-of-buffer)
    (insert-and-inherit buff-text) ;; впечатываем что нужно в буфер *SQL*
    (comint-send-input) ;; имитируем нажатие RET пользователем
    (switch-to-buffer curr-buff)))
Итого: изобрел свой велосипед вместо comint-send-region, код грубоват, зато работает как нужно. И без состояний (флага). Можно было бы и красивее, если бы знал, как впечатать строку в буфер без перехода в него (nonexistent-print-to-buffer buffername string-to-print).

ipc
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.