AsaAyers / code-links

MIT License
16 stars 8 forks source link

Extend process interface to get filepath, or better TextBuffer #8

Closed hedefalk closed 9 years ago

hedefalk commented 9 years ago

Original thread:

https://discuss.atom.io/t/position-of-mouse-click/15958/6

To clarify, I'm building integration with Ensime (https://github.com/ensime/ensime-server/) to try to get a full-fletched Scala IDE in Atom. Ensime is a client/server solution where a server works as a provider of IDE-related data. The server is started with a reference to the projects file location and then the editor/client can ask questions like "give me code-completions at this point of this file" and such.

I now have a very simple "jump-to-defintion" with keystrokes and also mouse-click. Mouse clicks are just implemented like so:

@subscriber.subscribe @scroll, 'mousedown', (e) =>
      {detail, shiftKey, metaKey, ctrlKey, altKey} = e
      pixelPt = pixelPositionFromMouseEvent(@editor, e)
      screenPt = @editor.screenPositionForPixelPosition(pixelPt)
      bufferPt = @editor.bufferPositionForScreenPosition(screenPt)
      buffer = @editor.getBuffer()
      if(altKey) then @client.goToTypeAtPoint(buffer, bufferPt)

where

sendAndThen: (msg, callback) =>
    swankMsg = buildMessage("(:swank-rpc #{msg} #{@ensimeMessageCounter})")
    @callbackMap[@ensimeMessageCounter++] = callback
    @socket.write(swankMsg)

  goToTypeAtPoint: (textBuffer, bufferPosition) =>
    offset = textBuffer.characterIndexForPosition(bufferPosition)
    file = textBuffer.getPath()
    @sendAndThen("(swank:type-at-point \"#{file}\" #{offset})", (msg) ->
      # (:return (:ok (:arrow-type nil :name "Ingredient" :type-id 3 :decl-as class :full-name "se.kostbevakningen.model.record.Ingredient" :type-args nil :members nil :pos (:type offset :file "/Users/viktor/dev/projects/kostbevakningen/src/main/scala/se/kostbevakningen/model/record/Ingredient.scala" :offset 545) :outer-type-id nil)) 3)
      pos = msg[":ok"]?[":pos"]
      targetFile = pos[":file"]
      targetOffset = pos[":offset"]
      console.log("targetFile: #{targetFile}")
      atom.workspace.open(targetFile).then (editor) ->
        targetEditorPos = editor.getBuffer().positionForCharacterIndex(parseInt(targetOffset))
        editor.setCursorScreenPosition(targetEditorPos)

It would be cooler to use code-links to mark out the links, but then I need the TextBuffer, not the contents to call this method:

https://github.com/ensime/ensime-server/blob/master/swank/src/main/scala/org/ensime/server/protocol/swank/SwankProtocol.scala#L1302

which I could use to get a list of all the symbols of a file.

hedefalk commented 9 years ago

By the way, @AsaAyers, do you know how to do settings for ctrl keys for mouse events? I would actually rather use cmd-click on Mac since this is the default of all IDE:s but that currently puts out a second cursor in Atom. I can't seem to find any settings for this, just simple key commands.

AsaAyers commented 9 years ago

code-links actually cancels the multi-cursor behavior when following links.

I don't have a mac, but to add cmd-click I'll need someone :wink: to contribute to the handler, config options, and keymap.

I actually avoided sending the TextBuffer because just sending the text makes it easier to write tests in plugins. You don't have to try to mock a buffer or setup a real buffer, it's just strings. Would it be sufficient to send process(source, { filename: ... }) instead? I'm thinking the second parameter could provide other metadata if needed.

hedefalk commented 9 years ago

Hm, I think I would prefer it a lot to get the TextBuffer. Thing is that I those "begin/end" offsets aren't optional when I ask for a list of symbols of the file so if I only get the filename I need to read it from file again to see how long it is.

If a TextBuffer I could also see if there are unsaved edits and patch the source before asking the server. That won't be possible with only filename.

hedefalk commented 9 years ago

Sorry to ask so much :)

AsaAyers commented 9 years ago

I'm not going to be maintaining code-links. No one else ever wrote a plugin for it, and hyperclick already does that half of what code-links was for. The other half, scanning JavaScript files, has been rewritten into js-hyperclick

hedefalk commented 9 years ago

Awesome! Didn't know about hyperclick. I might rewrite my homebrew to using that. Cheers.