#import "JubCLICommand.h"
#import "JubCLIUI.h"
+#include <string.h>
+
BEGINCLICOMMAND(JubCLIReplyCommand, @":r", nil,
@"Sets the sender of the last incomming message as the default recipient")
{
return;
}
- XMPPPresence *presence;
OFString *show = parameters[0];
if (![@[ @"available", @"away", @"dnd", @"xa", @"chat", @"unavailable" ]
containsObject: show]) {
- [of_stdout writeLine: @"<status> must be one of:"
+ [of_stdout writeLine: @"<status> must be one of: "
@"available, away, dnd, xa, chat, unavailable"];
return;
}
- if ([show isEqual: @"unavailable"])
- presence = [XMPPPresence presenceWithType: show];
- else
- presence = [XMPPPresence presence];
-
- if (![@[ @"available", @"unavailable" ] containsObject: show])
- presence.show = show;
-
if ([parameters count] == 2) {
- [_ui.client.connection sendStanza: presence];
+ [_ui.client sendPresenceWithStatus: show];
return;
}
- OFArray *message =
- [parameters arrayByRemovingObject: [parameters firstObject]];
- presence.status = [message componentsJoinedByString: @" "];
+ OFString *message = [[parameters
+ arrayByRemovingObject: [parameters firstObject]]
+ componentsJoinedByString: @" "];
- [_ui.client.connection sendStanza: presence];
+ [_ui.client sendPresenceWithStatus: show
+ text: message];
}
ENDCLICOMMAND
[super dealloc];
}
+static JubCLIUI *completionData;
+static void completionCallback(OFString *buf, OFList *lc)
+{
+ if ([buf length] < 3)
+ return;
+
+ if (![buf hasPrefix: @":s "] && ![buf hasPrefix: @":m "] &&
+ ![buf hasPrefix: @":t "])
+ return;
+
+ if ([buf hasPrefix: @":t"]) {
+ OFString *options[] = {
+ @":t available",
+ @":t away",
+ @":t dnd",
+ @":t xa",
+ @":t chat",
+ @":t unavailable"
+ };
+
+ for (int i = 0; i < 6; i++) {
+ if (![options[i] hasPrefix: buf])
+ continue;
+ [lc appendObject: options[i]];
+ }
+
+ return;
+ }
+
+ OFString *command = [buf substringWithRange: of_range(0, 3)];
+ OFString *query = [buf substringWithRange: of_range(3, [buf length]-3)];
+ OFDictionary *contacts = completionData.client.contactManager.contacts;
+ for (OFString *key in contacts) {
+ if (![key hasPrefix: query])
+ continue;
+ [lc appendObject: [command stringByAppendingString: key]];
+ }
+}
+
- (void)startUIThread
{
- [of_stdin asyncReadLineWithTarget: self
- selector: @selector(Jub_userInputWithStream:
- line:exception:)];
+ completionData = self;
+
+ [[OFThread threadWithBlock: ^(void) {
+ OFString *line;
+ Linenoise *reader = [Linenoise sharedLinenoise];
+ reader.multiline = true;
+ reader.completionCallback = completionCallback;
+
+ while ((line = [reader readInputWithPrompt: @"> "]) != nil) @autoreleasepool {
+ [self Jub_userInputWithStream: nil
+ line: line
+ exception: nil];
+ if ([line length] != 0)
+ [reader addHistoryItem: line];
+ }
+ [self Jub_userInputWithStream: nil
+ line: nil
+ exception: nil];
+
+ return nil;
+ }] start];
}
- (void)client: (JubChatClient*)client
line: (OFString*)line
exception: (OFException*)exception
{
- if (line == nil)
+ if (line == nil || exception != nil)
[OFApplication terminate];
if ([line length] == 0)
return YES;
if ([line characterAtIndex: 0] != ':') {
- if (_sink == nil)
+ if (_sink == nil) {
[of_stdout writeLine: @"No default sink selected, "
@"type `:h` for help"];
+ return YES;
+ }
[_sink send: line];
__block size_t longest = 0;
[_commands enumerateKeysAndObjectsUsingBlock:
- ^(OFString *key, id<JubCLICommand> command, BOOL *stop) {
+ ^(OFString *key, id<JubCLICommand> command, bool *stop) {
size_t length = [command.command length] +
(command.params == nil ? 0 :
(1 + [command.params length]));
- (void)contact: (XMPPContact*)contact
didSendPresence: (XMPPPresence*)presence
{
+ [of_stdout writeFormat: @"\r"];
[of_stdout writeFormat: BOLD("%@") @" is now in state ", presence.from];
if ([presence.type isEqual: @"unavailable"])
[of_stdout writeFormat: @": %@", presence.status];
[of_stdout writeString: @"\n"];
+
+ [[Linenoise sharedLinenoise] refreshLine];
}
@end