diff --git a/acvisitor.d b/acvisitor.d index e477e54..5592d5c 100644 --- a/acvisitor.d +++ b/acvisitor.d @@ -257,7 +257,7 @@ class AutocompleteVisitor : ASTVisitor if (dec.parameters !is null && parentSymbol !is null) { symbol.calltip = format("%s this%s", parentSymbol.name, - dec.parameters.toString()); + formatNode(dec.parameters)); } auto p = parentSymbol; parentSymbol = symbol; @@ -318,7 +318,7 @@ class AutocompleteVisitor : ASTVisitor { string returnType; if (dec.returnType !is null) - returnType = dec.returnType.toString(); + returnType = formatNode(dec.returnType); else { if (dec.hasAuto) diff --git a/build.bat b/build.bat index e47abc3..35660b9 100644 --- a/build.bat +++ b/build.bat @@ -1,2 +1,2 @@ dmd -wi client.d messages.d msgpack-d/src/msgpack.d -Imsgpack-d/src -ofdcd-client -L/exet:nt/su:windows:4.0 -dmd -wi -g server.d modulecache.d actypes.d messages.d constants.d acvisitor.d autocomplete.d dscanner/stdx/d/ast.d dscanner/stdx/d/parser.d dscanner/stdx/d/lexer.d dscanner/stdx/d/entities.d msgpack-d/src/msgpack.d -Imsgpack-d/src -Idscanner/ -ofdcd-server +dmd -wi -g server.d modulecache.d actypes.d messages.d constants.d acvisitor.d autocomplete.d dscanner/stdx/d/ast.d dscanner/stdx/d/parser.d dscanner/stdx/d/lexer.d dscanner/stdx/d/entities.d dscanner/formatter.d msgpack-d/src/msgpack.d -Imsgpack-d/src -Idscanner/ -ofdcd-server diff --git a/build.sh b/build.sh index 5018ce1..67ca672 100755 --- a/build.sh +++ b/build.sh @@ -1,2 +1,2 @@ dmd -wi client.d messages.d msgpack-d/src/msgpack.d -Imsgpack-d/src -ofdcd-client -dmd -wi -g server.d modulecache.d actypes.d messages.d constants.d acvisitor.d autocomplete.d dscanner/stdx/d/ast.d dscanner/stdx/d/parser.d dscanner/stdx/d/lexer.d dscanner/stdx/d/entities.d msgpack-d/src/msgpack.d dscanner/formatter.d -Imsgpack-d/src -Idscanner/ -ofdcd-server +dmd -wi -g server.d modulecache.d actypes.d messages.d constants.d acvisitor.d autocomplete.d dscanner/stdx/d/ast.d dscanner/stdx/d/parser.d dscanner/stdx/d/lexer.d dscanner/stdx/d/entities.d dscanner/formatter.d msgpack-d/src/msgpack.d -Imsgpack-d/src -Idscanner/ -ofdcd-server diff --git a/client.d b/client.d index fe6cd1f..c60c0b6 100644 --- a/client.d +++ b/client.d @@ -27,6 +27,7 @@ import std.algorithm; import std.path; import std.file; import std.conv; +import std.string; //version(Windows) //{ // import core.runtime; @@ -86,6 +87,7 @@ int /*_*/main(string[] args) catch (Exception e) { stderr.writeln(e.msg); + return 1; } if (help) @@ -100,34 +102,18 @@ int /*_*/main(string[] args) request.kind = RequestKind.shutdown; else if (clearCache) request.kind = RequestKind.clearCache; - auto socket = new TcpSocket(AddressFamily.INET); + TcpSocket socket = createSocket(port); scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); } - socket.connect(new InternetAddress("127.0.0.1", port)); - socket.blocking = true; - socket.setOption(SocketOptionLevel.TCP, SocketOption.TCP_NODELAY, 1); - ubyte[] message = msgpack.pack(request); - ubyte[] messageBuffer = new ubyte[message.length + message.length.sizeof]; - auto messageLength = message.length; - messageBuffer[0 .. size_t.sizeof] = (cast(ubyte*) &messageLength)[0 .. size_t.sizeof]; - messageBuffer[size_t.sizeof .. $] = message[]; - return socket.send(messageBuffer) == messageBuffer.length ? 0 : 1; + return sendRequest(socket, request) ? 0 : 1; } else if (importPaths.length > 0) { AutocompleteRequest request; request.kind = RequestKind.addImport; request.importPaths = importPaths.map!(a => isRooted(a) ? a : absolutePath(a)).array; - auto socket = new TcpSocket(AddressFamily.INET); + TcpSocket socket = createSocket(port); scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); } - socket.connect(new InternetAddress("127.0.0.1", port)); - socket.blocking = true; - socket.setOption(SocketOptionLevel.TCP, SocketOption.TCP_NODELAY, 1); - ubyte[] message = msgpack.pack(request); - ubyte[] messageBuffer = new ubyte[message.length + message.length.sizeof]; - auto messageLength = message.length; - messageBuffer[0 .. size_t.sizeof] = (cast(ubyte*) &messageLength)[0 .. size_t.sizeof]; - messageBuffer[size_t.sizeof .. $] = message[]; - return socket.send(messageBuffer) == messageBuffer.length ? 0 : 1; + return sendRequest(socket, request) ? 0 : 1; } else if (cursorPos == size_t.max) { @@ -169,48 +155,34 @@ int /*_*/main(string[] args) request.importPaths = importPaths; request.sourceCode = sourceCode; request.cursorPosition = cursorPos; - ubyte[] message = msgpack.pack(request); // Send message to server - TcpSocket socket = new TcpSocket(AddressFamily.INET); - socket.setOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, dur!"seconds"(5)); + TcpSocket socket = createSocket(port); scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); } - socket.connect(new InternetAddress("127.0.0.1", port)); - socket.blocking = true; - ubyte[] messageBuffer = new ubyte[message.length + message.length.sizeof]; - auto messageLength = message.length; - messageBuffer[0 .. size_t.sizeof] = (cast(ubyte*) &messageLength)[0 .. size_t.sizeof]; - messageBuffer[size_t.sizeof .. $] = message[]; - auto bytesSent = socket.send(messageBuffer); - - // Get response and write it out - ubyte[1024 * 16] buffer; - auto bytesReceived = socket.receive(buffer); - if (bytesReceived == Socket.ERROR) - { + if (!sendRequest(socket, request)) return 1; - } - AutocompleteResponse response; - msgpack.unpack(buffer[0..bytesReceived], response); + AutocompleteResponse response = getResponse(socket); if (response.completions.length > 0) { writeln(response.completionType); + auto app = appender!(string[])(); if (response.completionType == CompletionType.identifiers) { for (size_t i = 0; i < response.completions.length; i++) - { - writefln("%s\t%s", response.completions[i], response.completionKinds[i]); - } + app.put(format("%s\t%s", response.completions[i], response.completionKinds[i])); } else { foreach (completion; response.completions) { - writeln(completion); + app.put(completion); } } + // Deduplicate overloaded methods + foreach (line; app.data.sort.uniq) + writeln(line); } return 0; } @@ -249,3 +221,39 @@ Options: Uses PORTNUMBER to communicate with the server instead of the default port 9166.`, programName); } + +TcpSocket createSocket(ushort port) +{ + TcpSocket socket = new TcpSocket(AddressFamily.INET); + socket.setOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, dur!"seconds"(5)); + socket.connect(new InternetAddress("localhost", port)); + socket.blocking = true; + return socket; +} + +/** + * Returns: true on success + */ +bool sendRequest(TcpSocket socket, AutocompleteRequest request) +{ + ubyte[] message = msgpack.pack(request); + ubyte[] messageBuffer = new ubyte[message.length + message.length.sizeof]; + auto messageLength = message.length; + messageBuffer[0 .. size_t.sizeof] = (cast(ubyte*) &messageLength)[0 .. size_t.sizeof]; + messageBuffer[size_t.sizeof .. $] = message[]; + return socket.send(messageBuffer) == messageBuffer.length; +} + +/** + * Gets the response from the server + */ +AutocompleteResponse getResponse(TcpSocket socket) +{ + ubyte[1024 * 16] buffer; + auto bytesReceived = socket.receive(buffer); + if (bytesReceived == Socket.ERROR) + throw new Exception("Incorrect number of bytes received"); + AutocompleteResponse response; + msgpack.unpack(buffer[0..bytesReceived], response); + return response; +} diff --git a/editors/textadept/modules/dmd/dcd.lua b/editors/textadept/modules/dmd/dcd.lua index 4161a4a..4656e21 100644 --- a/editors/textadept/modules/dmd/dcd.lua +++ b/editors/textadept/modules/dmd/dcd.lua @@ -58,8 +58,10 @@ local function showCompletionList(r) end table.sort(completions, function(a, b) return string.upper(a) < string.upper(b) end) local charactersEntered = buffer.current_pos - buffer:word_start_position(buffer.current_pos) - if buffer.char_at[buffer.current_pos - 1] == string.byte('.') then charactersEntered = 0 end - print(charactersEntered) + if buffer.char_at[buffer.current_pos - 1] == string.byte('.') + or buffer.char_at[buffer.current_pos - 1] == string.byte('(') then + charactersEntered = 0 + end buffer:auto_c_show(charactersEntered, table.concat(completions, " ")) --buffer.auto_c_fill_ups = "(.[" buffer.auto_c_choose_single = setting @@ -111,11 +113,7 @@ function M.autocomplete(ch) if buffer:get_lexer() ~= "dmd" then return end local fileName = os.tmpname() local command = M.PATH_TO_DCD_CLIENT .. " -c" .. buffer.current_pos .. " > " .. fileName - local mode = "w" - if _G.WIN32 then - mode = "wb" - end - p = io.popen(command, mode) + local p = io.popen(command, "wb") p:write(buffer:get_text()) p:flush() p:close() diff --git a/server.d b/server.d index 3bdbc01..689dcbf 100644 --- a/server.d +++ b/server.d @@ -63,7 +63,7 @@ int main(string[] args) auto socket = new TcpSocket(AddressFamily.INET); socket.blocking = true; socket.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, true); - socket.bind(new InternetAddress("127.0.0.1", port)); + socket.bind(new InternetAddress("localhost", port)); socket.listen(0); scope (exit) {