Как получить базовую интеграцию приложения <-> Emacs? - PullRequest
11 голосов
/ 31 марта 2009

Существует множество приложений, которые интегрируют Emacs с внешними процессами. GDB - это тот, который приходит на ум. Я могу управлять GDB из emacs, а затем получать отзывы на экране.

Я бы хотел сделать что-то в этом направлении с моим заявлением.

Вот что я хочу:

  • установить связь между мной и emacs. Я, вероятно, запустил бы новый процесс emacs и добавил бы его в свой графический интерфейс
  • указать emacs для отображения файла. (легко с истощением)
  • приказывает emacs прокрутить центр по определенному номеру строки и hilite или просто переместить курсор туда.
    • Вероятно, реальный вопрос заключается в том, как отправить произвольный код elisp из моего внешнего приложения для выполнения emacs.
    • Я не говорю на элиспе, но это было бы отличным поводом для изучения
  • предоставляет некоторые кликабельные области в буфере emacs, которые при запуске отправят сообщение обратно в мое приложение.
    • Даже если щелкнуть мышью, связка клавиш, отправляющая сообщение, будет началом. (но я знаю, что активная вещь возможна, поэтому я спрашиваю)

Я знаю, что это все возможно (что не возможно в emacs?), Но я просто не знаю, где начать поиск в Google.

Ответы [ 7 ]

5 голосов
/ 31 марта 2009

Это зависит от того, как вы хотите все настроить. Определенно часть руководства по процессам стоит прочитать. Чтение кода для пакета 'comint - хорошее место для начала.

Вы перечислили довольно ограниченный набор функций, которые вы хотели бы показать, которые могут быть решены с помощью прямого подключения. Вы можете найти полезные служебные функции, взглянув на то, что предусмотрено в 'net-utils (M-x find-library net-utils RET).

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

Запуск Emacs из приложения

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

  • написать небольшой скрипт на Perl, чтобы открыть сокет и читать / писать в него
  • установить цикл (read (eval (print))) в интерпретаторе (или написать собственный) и подключить его к сокету / порту
  • запуск Emacs с вызовом функции (--eval или --execute) с указанием сокета
  • запустить сценарий perl как подпроцесс и порт (смотрите, как это делают inferior-lisp или inferior-tcl )

В этот момент все, что есть в Emacs, может быть отправлено в подпроцесс perl ('comint-send-string) и передано в ваш REPL , и там вы получите желаемый эффект. Аналогично, вы можете отправлять команды обратно в emacs, просто отправляя через строки и анализируя их по функциям, которые вы вставили в 'comint-output-filter-functions.

Затем вы написали бы две маленькие библиотеки, одну на интерпретируемом для вашего APP языке, а другую в Emacs, чтобы выполнять любые функции, которые имеют смысл. Библиотека emacs, вероятно, должна быть упакована как основной (или второстепенный) режим в зависимости от того, на что похожи файлы. Если они используются исключительно с приложением, основным режимом, если это (например) файлы C ++, второстепенный режим будет лучше, если учесть, что вы, вероятно, захотите использовать режим c ++.

Я бы написал маленький скрипт на perl, в отличие от elisp, просто б / к, я знаю, как взаимодействовать с comint. Если маленький Perl-скрипт можно заменить на кусок elisp, и при этом получить преимущество, используя comint, это будет дополнительным бонусом.

У меня почти такая же настройка для Tcl / Tk, только команда соединения обрабатывает только соединение. Это работает очень хорошо.

Запуск приложения из Emacs

Теперь, если вы могли бы вместо этого запустить приложение из Emacs, все вышеописанное применимо, только вы можете избавиться от маленького Perl-скрипта и просто взаимодействовать через интерфейс 'comint. Розетки не нужны.

  • Вам по-прежнему нужен цикл 'repl (если приложение не может привязать stdin / stdout к интерпретатору
  • Библиотеки останутся прежними

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

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

5 голосов
/ 31 марта 2009

интерактивные области

Библиотека виджетов позволит вам превратить части вашего буфера в кнопки (а также в переключатели, флажки, списки), которые будут выполнять elisp при нажатии на них Например:

    (require 'widget)

(defun simple-widget-example ()
   (interactive)
  (switch-to-buffer "*Simple widget example*")

  (let ((inhibit-read-only t))
    (erase-buffer))

  (let ((all (overlay-lists)))
    ;; Delete all the overlays.
    (mapcar 'delete-overlay (car all))
    (mapcar 'delete-overlay (cdr all)))

  (widget-insert "Sample button\n")
  (widget-create 'push-button
         :notify (lambda (&rest ignore) 
               (message "Poop! Ha Ha!"))
         "Press Me")

  (use-local-map widget-keymap)

  (widget-setup))

См. Библиотека виджетов Emacs

5 голосов
/ 31 марта 2009

Возможно, вы захотите взглянуть на Distel (интеграция Emacs с системой сообщений Erlang) и SLIME (интерфейс между Emacs и Common Lisp). Это два режима Emacs, которые включают в себя довольно впечатляющую интеграцию другой системы, говоря с ней асинхронно. В частности, есть статья о том, как был реализован Distel, а также некоторые другие полезные сведения о том, как он работает здесь .

3 голосов
/ 31 марта 2009

Вам нужен асинхронный процесс , который общается с Emacs. Посмотрите в руководстве по Emacs в разделе процессы . Хорошее место для начала может быть с функциями start-process или start-process-shell-command.

Например, код вы можете посмотреть на источник для команды man, распространяемой вместе с emacs, или на источник для vc-do-command. (Чтобы увидеть исходный код, введите C-h f, затем имя функции, а затем щелкните имя функции в окне справки.)

1 голос
/ 31 марта 2009

В общем, вы должны посмотреть в руководстве по emacs .

В качестве третьего пункта взгляните на параметры командной строки emacs. В частности, --eval и -f.

0 голосов
/ 31 марта 2009

Я не уверен, насколько это поможет, но вы, возможно, захотите взглянуть на реализацию SLIME , которая, хотя и ориентирована на lisp, имеет некоторые очень приятные функции. Например, вы можете настроить его так, чтобы он легко подключался к запущенному процессу. Не совсем то, что вы хотите, но у него есть все части и довольно гладко.

0 голосов
/ 31 марта 2009

чтобы заставить emacs выполнять код lisp, просто создайте интерактивную функцию, а затем вы можете вызвать ее, используя имя функции M-x Ниже приведена основная функция, которая откроет файл.

    (defun na-reopen-file ()
  "Reopen file in buffer."
  (interactive)
  (let ((p (point)))
    (progn
      (find-alternate-file buffer-file-name)
      (goto-char p) ) ) )

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

Для создания кликабельных ссылок вы можете использовать следующие функции

  (make-button beg end 'action 'nmap-clear-buffer 'follow-link t)
  ;;for color
  (put-text-property beg end 'face nmap-active-button )
...