Sorting / Filtering results

I've been playing around with building an auto-completion package for Atom (my specific need is for Linux, so I can't use autocomplete-swift which relies on SourceKittenDaemon which appears not to be ported yet.

I've got something crude working, but I'm a bit suspicious about the results I'm getting back, and I'm also wondering if anyone has some tried and tested strategies for filtering/sorting them to avoid overloading the user with unhelpful stuff.

As an example of why I'm suspicious of the results, if I give the plugin this input:

import Foundation

let x = UR

I don't get any suggestions back, which I'm surprised about. I would hope to have it suggest "URL".

On the other hand, if I give it:

import Foundation

let x = URL

I do get suggestions for the various init methods for URL - so it clearly knows about it, and I do appear to be passing it something approximating the correct context.

Anyone got any ideas which stupid thing I might have done?

For a more reproducible test:

> sourcekitten complete --text "import Foundation; let x = UR" --offset 29
<unknown>:0: error: compiler is in code completion mode (benign diagnostic)
[]

as opposed to:

> sourcekitten complete --text "import Foundation; let x = URL" --offset 30 | grep "name"
<unknown>:0: error: compiler is in code completion mode (benign diagnostic)
  "name" : "(dataRepresentation:relativeTo:)",
  "name" : "(dataRepresentation:relativeTo:isAbsolute:)",
  "name" : "(fileReferenceLiteralResourceName:)",
  "name" : "(fileURLWithFileSystemRepresentation:isDirectory:relativeTo:)",
  "name" : "(fileURLWithPath:)",
  "name" : "(fileURLWithPath:isDirectory:)",
  "name" : "(fileURLWithPath:isDirectory:relativeTo:)",
  "name" : "(fileURLWithPath:relativeTo:)",
  "name" : "(from:)",
  "name" : "(string:)",
  "name" : "(string:relativeTo:)",
  "name" : "_bridgeToAnyObject()",
  "name" : "_bridgeToObjectiveC()",
  "name" : "_conditionallyBridgeFromObjectiveC(:result:)",
  "name" : "_forceBridgeFromObjectiveC(:result:)",
  "name" : "_ObjectType",
  "name" : "_unconditionallyBridgeFromObjectiveC(:)",
  "name" : "appendingPathComponent()",
  "name" : "appendingPathComponent()",
  "name" : "appendingPathExtension()",
  "name" : "appendPathComponent()",
  "name" : "appendPathComponent()",
  "name" : "appendPathExtension()",
  "name" : "checkResourceIsReachable()",
  "name" : "deleteLastPathComponent()",
  "name" : "deletePathExtension()",
  "name" : "deletingLastPathComponent()",
  "name" : "deletingPathExtension()",
  "name" : "encode()",
  "name" : "hash()",
  "name" : "ReferenceType",
  "name" : "removeAllCachedResourceValues()",
  "name" : "removeCachedResourceValue()",
  "name" : "resolveSymlinksInPath()",
  "name" : "resolvingSymlinksInPath()",
  "name" : "resourceValues()",
  "name" : "setResourceValues()",
  "name" : "setTemporaryResourceValue()",
  "name" : "standardize()",
  "name" : "withUnsafeFileSystemRepresentation()",

Some of the completions that you get in Xcode, seem to be implemented on the Xcode side, not the sourcekit side. Related issue about this: Completion limitations · Issue #113 · jpsim/SourceKitten · GitHub

I think this would explain your URL type completion case

Thanks, that's... somewhat counter-intuitive!

It seems that I can achieve something close to what I'm after by taking what Atom thinks the prefix is and giving the start of it as the offset, then filtering the results to strip out any that don't begin with the prefix.

All of which is fine as far as it goes, but it's a little weird that SourceKit itself isn't doing that stuff. Especially as there are some edge cases I think, such as the prefix being empty, or just '.'.

No doubt I can figure it out, but you'd think that SourceKit would be the logical place to do it since it (presumably) has all the context, whereas at the level I'm working it's just a bunch of characters :slight_smile:

Try SourceKitten. It's pretty nice :slight_smile:

It wraps SourceKit pretty nicely.

That's what I'm using :slight_smile:

1 Like

The behavior coming from SourceKit itself here is counter-intuitive (SourceKit proper rather than SourceKitten). I would welcome a PR that would bake some of this enhanced logic into SourceKitten with a special flag.

1 Like