mmccoo
mmccoo

Reputation: 8546

How do I get basic App<->Emacs integration?

There are a bunch of applications out there that integrate Emacs with external processes. GDB is one that comes to mind. I can control GDB from emacs and then get feedback on the screen.

I'd like to do something in that direction with my application.

Here's what I want:

I know that this is all possible (what isn't possible in emacs?), but I just don't know where to start googling.

Upvotes: 11

Views: 1576

Answers (7)

justinhj
justinhj

Reputation: 11316

Clickable Areas

The widget library would let you make parts of your buffer into buttons (also radio boxes, check boxes, lists), which will execute elisp when you click them. For example:

    (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))

See Emacs Widget Library

Upvotes: 5

simon
simon

Reputation: 7022

I'm not sure how much it will help, but you might want to have a look at the implementation of SLIME which, while lisp oriented, has some very nice features. You can set it up to attach to a running process easily, for example. Not exactly what you want, but it's got all the pieces and is pretty slick.

Upvotes: 0

Trey Jackson
Trey Jackson

Reputation: 74480

It kind of depends on how you want to set things up. Definitely the portion of the manual on processes is worth reading. Reading the code for 'comint package is a good place to start.

You've listed a pretty limited set of functionality you'd like to expose, which could be solved by a direct connection. You can find helpful utility functions by looking at what is provided in 'net-utils (M-x find-library net-utils RET).

If the application you're trying to connect to has an interpreted language, I'd connect to that, as opposed to writing a custom parser on the app side.

Launching Emacs From App

Since you're launching Emacs from the app (as opposed to the other way (which might have made this job easier)), this is what I'd probably do:

  • write little perl script to open a socket and read/write to it
  • set up '(read (eval (print))) loop in the interpreter (or write a custom one) and connect it to a socket/port
  • launch Emacs with function call (--eval or --execute) specifying the socket
  • start the perl script as a subprocess and the port (see how inferior-lisp or inferior-tcl do it)

At that point, anything from Emacs could be sent to the perl subprocess ('comint-send-string), and be passed on to your REPL and have the desired effect there. Likewise, you can send commands back to emacs by just sending over strings, and have them parsed by functions you've stuck in 'comint-output-filter-functions.

You'd then write two little libraries, one in your APP interpreted language, and one in Emacs, to do whatever functionality makes sense. The emacs library should probably be packaged as a major (or minor) mode depending on what the files are like. If they're solely to be used with the app, a major mode, if they're (for example) C++ files, a minor mode would be better given that you'd probably want to leverage the c++-mode.

I'd write the little perl script in perl, as opposed to elisp, simply b/c I know how to interact with 'comint. If the little perl script could be replaced with a chunk of elisp, and still have the benefit using comint, that'd be an added bonus.

I've got pretty much the same setup for Tcl/Tk, only the connection stuff is handled by Tk's send command. It works really well.

Launching App From Emacs

Now, if you could, instead, launch the app from Emacs, the above still applies, only you can get rid of the little perl script and just interact through the 'comint interface. No sockets needed.

  • You'd still need the 'repl loop (if the app can't leave stdin/stdout tied to the interpreter
  • The libraries would remain the same

That'd be much easier, but only works if the user flow enables you to go that direction. (I've a hunch you're writing this for more than just your use.)

That being said, it might be easier to develop/test this way (launching from Emacs). You could add on the socket communication later as an enhancement. Whichever is more motivating...

Upvotes: 5

Brian Campbell
Brian Campbell

Reputation: 333136

You might want to look at Distel (an integration of Emacs with Erlang's message system) and SLIME (an interface between Emacs and Common Lisp). These are two Emacs modes that involve a quite impressive integration of another system by talking to it asynchronously. In particular, there is a paper on how Distel was implemented, along with some other good information on how it works here.

Upvotes: 5

Norman Ramsey
Norman Ramsey

Reputation: 202655

You want an asynchronous process that talks to Emacs. Look in the Emacs manual in the section on processes. A good place to start might be with the start-process or start-process-shell-command functions.

For example code you could look at the source for the man command distributed with emacs, or the source for vc-do-command. (To see source code, type C-h f then the function name and then click on the name of the function in the help window.)

Upvotes: 3

Hamza Yerlikaya
Hamza Yerlikaya

Reputation: 421

to make emacs execute lisp code just create a function that is interactive and then you can call it using M-x function-name. Following is a basic function that will reopen file.

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

For interacting with your application you can run a async process and comunicate with it using a buffer. check the start-process function in the manual.

For creating click able links you can use the following functions

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

Upvotes: 0

T.E.D.
T.E.D.

Reputation: 44814

In general, you should look around in the emacs manual.

For your third bullet, take a look at emacs' command line options. In particular, --eval and -f.

Upvotes: 1

Related Questions