Как мне получить базовую интеграцию App ‹-› Emacs?

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

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

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

  • установить связь между мной и emacs. Я бы, вероятно, запустил новый процесс emacs и вставил его в свой графический интерфейс
  • скажите emacs отобразить файл. (легко с emacsclient)
  • tell emacs to scroll to center on a particular line number and hilite or just move the cursor there.
    • Probably the real question is how do I send arbitrary elisp code from my external app for emacs to execute.
    • Я не говорю на elisp, но это был бы отличный повод узнать
  • provide some clickable areas in the emacs buffer that, when triggered, will send a message back to my app.
    • Even short of clickability, a key-binding that sends the message would be a start. (but I know the clickable thing is possible, so I'm asking)

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


person mmccoo    schedule 30.03.2009    source источник
comment
Пришло время укусить пулю.   -  person Trey Jackson    schedule 31.03.2009
comment
Ни один из представленных ответов не дал ответа на ваш вопрос? Если вы получили ответ, примите его. Если нет, то уточните вопрос. Все ответы, которые я здесь вижу, полезны, но, возможно, вопрос не в том, что люди поняли.   -  person Drew    schedule 12.10.2013


Ответы (7)


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

person Brian Campbell    schedule 31.03.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.

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

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

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

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

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

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

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

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

person Trey Jackson    schedule 31.03.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

person justinhj    schedule 31.03.2009

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

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

person Norman Ramsey    schedule 31.03.2009

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

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

person T.E.D.    schedule 30.03.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 )
person Hamza Yerlikaya    schedule 30.03.2009
comment
для выполнения abritrary elisp я имел в виду, что хочу отправить этот код извне emacs. Я немного отредактировал вопрос, чтобы уточнить. Я попробую другую часть вашего ответа - person mmccoo; 31.03.2009

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

person simon    schedule 31.03.2009