[cmdopts] A bit of progress
authorMyhailo Danylenko <isbear@ukrpost.net>
Sun, 24 Mar 2013 00:59:26 +0200
changeset 84 6ff846816073
parent 83 1cfa0330a32c
child 85 93c3cc0d7891
[cmdopts] A bit of progress
cmdopts.diff
--- a/cmdopts.diff	Sat Mar 23 04:20:56 2013 +0200
+++ b/cmdopts.diff	Sun Mar 24 00:59:26 2013 +0200
@@ -11,7 +11,10 @@
     - status/status_to
     - add/del
     - group
-    - say
+    - say/msay/say_to
+    - buffer
+    - clear
+    - info
   * it does compile, but have not tested at all
   * privatized say_cmd()
   * dropped cmd_setstatus()
@@ -39,7 +42,7 @@
 
 diff -r 1b0b563a81e6 mcabber/doc/HOWTO_commands.mdwn
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/mcabber/doc/HOWTO_commands.mdwn	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/HOWTO_commands.mdwn	Sun Mar 24 00:58:15 2013 +0200
 @@ -0,0 +1,977 @@
 +
 +**New commands interface for MCabber**
@@ -1020,7 +1023,7 @@
 +<!-- vim: se ts=4 sw=4 et filetype=markdown tw=80: -->
 diff -r 1b0b563a81e6 mcabber/doc/help/cs/hlp_buffer.txt
 --- a/mcabber/doc/help/cs/hlp_buffer.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/cs/hlp_buffer.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/cs/hlp_buffer.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -25,7 +25,7 @@
   Přesune se o [n] řádků nahoru (výchozí: polovina obrazovky).
  /buffer down [n]
@@ -1032,7 +1035,7 @@
   Přesune se na procentuální pozici n%.
 diff -r 1b0b563a81e6 mcabber/doc/help/cs/hlp_del.txt
 --- a/mcabber/doc/help/cs/hlp_del.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/cs/hlp_del.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/cs/hlp_del.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,4 @@
  
 - /DEL
@@ -1041,7 +1044,7 @@
  Smaže aktuální kontakt ze seznamu kontaktů (rosteru) a zruší povolení oznamování o stavu daného kontaktu (autorizaci) na obou stranách.
 diff -r 1b0b563a81e6 mcabber/doc/help/cs/hlp_move.txt
 --- a/mcabber/doc/help/cs/hlp_move.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/cs/hlp_move.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/cs/hlp_move.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,5 +1,6 @@
  
 - /MOVE [skupina]
@@ -1052,7 +1055,7 @@
  Tip: V módu rozhovoru lze použít "/roster alternate" pro skok na přesunutý kontakt.
 diff -r 1b0b563a81e6 mcabber/doc/help/cs/hlp_rename.txt
 --- a/mcabber/doc/help/cs/hlp_rename.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/cs/hlp_rename.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/cs/hlp_rename.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,6 @@
  
 - /RENAME jméno
@@ -1064,7 +1067,7 @@
 +Optionally you can use one of --jid, --group or --name to select object, different from current.
 diff -r 1b0b563a81e6 mcabber/doc/help/de/hlp_buffer.txt
 --- a/mcabber/doc/help/de/hlp_buffer.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/de/hlp_buffer.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/de/hlp_buffer.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -25,7 +25,7 @@
   Scrollt den Puffer um n Zeilen hoch. Gibt man keine Zahl an, scrollt er um einen halben Bildschirm
  /buffer down [n]
@@ -1076,7 +1079,7 @@
   Springe zur Position "n" im Chatpuffer
 diff -r 1b0b563a81e6 mcabber/doc/help/de/hlp_del.txt
 --- a/mcabber/doc/help/de/hlp_del.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/de/hlp_del.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/de/hlp_del.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,4 @@
  
 - /DEL
@@ -1085,7 +1088,7 @@
  Löscht den gerade ausgewählten Buddy vom Roster. Außerdem werden die automatischen Presence Benachrichtigungen vom/zum Buddy gestoppt.
 diff -r 1b0b563a81e6 mcabber/doc/help/de/hlp_move.txt
 --- a/mcabber/doc/help/de/hlp_move.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/de/hlp_move.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/de/hlp_move.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,6 +1,7 @@
  
 - /MOVE [groupname]
@@ -1097,7 +1100,7 @@
  Tipp: Wenn der Chatmodus aktiviert ist, kannst du "/roster alternate" benutzen um zu dem gerade bewegten Buddy zu springen.
 diff -r 1b0b563a81e6 mcabber/doc/help/de/hlp_rename.txt
 --- a/mcabber/doc/help/de/hlp_rename.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/de/hlp_rename.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/de/hlp_rename.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,6 @@
  
 - /RENAME name
@@ -1109,7 +1112,7 @@
 +Optionally you can use one of --jid, --group or --name to select object, different from current.
 diff -r 1b0b563a81e6 mcabber/doc/help/en/hlp_buffer.txt
 --- a/mcabber/doc/help/en/hlp_buffer.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/en/hlp_buffer.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/en/hlp_buffer.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -25,7 +25,7 @@
   Scroll the buffer up [n] lines (default: half a screen)
  /buffer down [n]
@@ -1121,7 +1124,7 @@
   Jump to position %n of the buddy chat buffer
 diff -r 1b0b563a81e6 mcabber/doc/help/en/hlp_del.txt
 --- a/mcabber/doc/help/en/hlp_del.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/en/hlp_del.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/en/hlp_del.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,4 @@
  
 - /DEL
@@ -1131,7 +1134,7 @@
 +Delete the current buddy or one, specified with [jid] from our roster, unsubscribe from its presence notification and unsubscribe it from ours.
 diff -r 1b0b563a81e6 mcabber/doc/help/en/hlp_move.txt
 --- a/mcabber/doc/help/en/hlp_move.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/en/hlp_move.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/en/hlp_move.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,5 +1,6 @@
  
 - /MOVE [groupname]
@@ -1142,7 +1145,7 @@
  Tip: if the chatmode is enabled, you can use "/roster alternate" to jump to the moved buddy.
 diff -r 1b0b563a81e6 mcabber/doc/help/en/hlp_rename.txt
 --- a/mcabber/doc/help/en/hlp_rename.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/en/hlp_rename.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/en/hlp_rename.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,6 @@
  
 - /RENAME name
@@ -1154,7 +1157,7 @@
 +Optionally you can use one of --jid, --group or --name to select object, different from current.
 diff -r 1b0b563a81e6 mcabber/doc/help/fr/hlp_buffer.txt
 --- a/mcabber/doc/help/fr/hlp_buffer.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/fr/hlp_buffer.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/fr/hlp_buffer.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -25,7 +25,7 @@
   Défile vers le haut de [n] lignes (par défaut un demi écran)
  /buffer down [n]
@@ -1166,7 +1169,7 @@
   Va à la position n% du tampon
 diff -r 1b0b563a81e6 mcabber/doc/help/fr/hlp_del.txt
 --- a/mcabber/doc/help/fr/hlp_del.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/fr/hlp_del.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/fr/hlp_del.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,4 @@
  
 - /DEL
@@ -1175,7 +1178,7 @@
  Supprime le contact sélectionné du roster, supprime notre abonnement à ses notifications de présence et supprime son abonnement aux nôtres.
 diff -r 1b0b563a81e6 mcabber/doc/help/fr/hlp_move.txt
 --- a/mcabber/doc/help/fr/hlp_move.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/fr/hlp_move.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/fr/hlp_move.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,5 +1,6 @@
  
 - /MOVE [groupname]
@@ -1186,7 +1189,7 @@
  Astuce : si le mode discussion (chatmode) est activé, vous pouvez utiliser "/roster alternate" pour vous positionner sur le contact que vous venez de déplacer.
 diff -r 1b0b563a81e6 mcabber/doc/help/fr/hlp_rename.txt
 --- a/mcabber/doc/help/fr/hlp_rename.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/fr/hlp_rename.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/fr/hlp_rename.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,6 @@
  
 - /RENAME nom
@@ -1198,7 +1201,7 @@
 +Optionally you can use one of --jid, --group or --name to select object, different from current.
 diff -r 1b0b563a81e6 mcabber/doc/help/it/hlp_buffer.txt
 --- a/mcabber/doc/help/it/hlp_buffer.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/it/hlp_buffer.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/it/hlp_buffer.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -25,7 +25,7 @@
   Fa scorrere indietro il buffer di [n] linee (default: metà schermo)
  /buffer down [n]
@@ -1210,7 +1213,7 @@
   Salta alla posizione %n del buffer di chat corrente
 diff -r 1b0b563a81e6 mcabber/doc/help/it/hlp_del.txt
 --- a/mcabber/doc/help/it/hlp_del.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/it/hlp_del.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/it/hlp_del.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,4 @@
  
 - /DEL
@@ -1219,7 +1222,7 @@
  Elimina il contatto corrente dal roster, cancellando la sottoscrizione alle reciproche notifiche della propria presenza.
 diff -r 1b0b563a81e6 mcabber/doc/help/it/hlp_move.txt
 --- a/mcabber/doc/help/it/hlp_move.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/it/hlp_move.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/it/hlp_move.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,5 +1,6 @@
  
 - /MOVE [gruppo]
@@ -1230,7 +1233,7 @@
  Trucco: se la modalità chat è abilitata, puoi usare "/roster alternate" per spostarti sul contatto appena mosso.
 diff -r 1b0b563a81e6 mcabber/doc/help/it/hlp_rename.txt
 --- a/mcabber/doc/help/it/hlp_rename.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/it/hlp_rename.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/it/hlp_rename.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,6 @@
  
 - /RENAME nome
@@ -1242,7 +1245,7 @@
 +Optionally you can use one of --jid, --group or --name to select object, different from current.
 diff -r 1b0b563a81e6 mcabber/doc/help/nl/hlp_buffer.txt
 --- a/mcabber/doc/help/nl/hlp_buffer.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/nl/hlp_buffer.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/nl/hlp_buffer.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -25,7 +25,7 @@
   Scroll de buffer [n] regels omhoog (standaard: een half scherm)
  /buffer down [n]
@@ -1254,7 +1257,7 @@
   Spring naar positie %n in de buddy chat buffer
 diff -r 1b0b563a81e6 mcabber/doc/help/nl/hlp_del.txt
 --- a/mcabber/doc/help/nl/hlp_del.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/nl/hlp_del.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/nl/hlp_del.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,4 @@
  
 - /DEL
@@ -1263,7 +1266,7 @@
  Verwijder de actieve buddy uit ons roster, en zet het wederzijds toezenden van status veranderingen stop.
 diff -r 1b0b563a81e6 mcabber/doc/help/nl/hlp_move.txt
 --- a/mcabber/doc/help/nl/hlp_move.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/nl/hlp_move.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/nl/hlp_move.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,5 +1,6 @@
  
 - /MOVE [groepsnaam]
@@ -1274,7 +1277,7 @@
  Tip: indien chatmode actief is, kun je "/roster alternate" gebruiken om direct naar de verplaatste buddy te springen.
 diff -r 1b0b563a81e6 mcabber/doc/help/nl/hlp_rename.txt
 --- a/mcabber/doc/help/nl/hlp_rename.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/nl/hlp_rename.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/nl/hlp_rename.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,6 @@
  
 - /RENAME naam
@@ -1286,7 +1289,7 @@
 +Optionally you can use one of --jid, --group or --name to select object, different from current.
 diff -r 1b0b563a81e6 mcabber/doc/help/pl/hlp_del.txt
 --- a/mcabber/doc/help/pl/hlp_del.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/pl/hlp_del.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/pl/hlp_del.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,4 @@
  
 - /DEL
@@ -1295,7 +1298,7 @@
  Usuwa aktualnie zaznaczoną osobę z rostera, usuwa subskrypcję powiadomienia dostępności u danej osoby oraz u nas.
 diff -r 1b0b563a81e6 mcabber/doc/help/pl/hlp_move.txt
 --- a/mcabber/doc/help/pl/hlp_move.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/pl/hlp_move.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/pl/hlp_move.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,5 +1,6 @@
  
 - /MOVE [nazwa grupy]
@@ -1306,7 +1309,7 @@
  Podpowiedź: jeśli jest włączony tryb czatu, możesz użyć "/roster alternate" aby skoczyć do przeniesionej osoby.
 diff -r 1b0b563a81e6 mcabber/doc/help/pl/hlp_rename.txt
 --- a/mcabber/doc/help/pl/hlp_rename.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/pl/hlp_rename.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/pl/hlp_rename.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,6 @@
  
 - /RENAME nazwa
@@ -1318,7 +1321,7 @@
 +Optionally you can use one of --jid, --group or --name to select object, different from current.
 diff -r 1b0b563a81e6 mcabber/doc/help/ru/hlp_buffer.txt
 --- a/mcabber/doc/help/ru/hlp_buffer.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/ru/hlp_buffer.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/ru/hlp_buffer.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -25,7 +25,7 @@
   Перемещает на [n] строк вверх в буфере (истории переписки) (по умолчанию: половина экрана)
  /buffer down [n]
@@ -1330,7 +1333,7 @@
   Перемещает на позицию %n в текущем буфере (истории переписки)
 diff -r 1b0b563a81e6 mcabber/doc/help/ru/hlp_del.txt
 --- a/mcabber/doc/help/ru/hlp_del.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/ru/hlp_del.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/ru/hlp_del.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,4 @@
  
 - /DEL
@@ -1340,7 +1343,7 @@
 +Удаляет текущего пользователя (или указанного с помощью jid) из списка контактов, отключает уведомления о его статусе и отключает уведомление пользователя о вашем статусе.
 diff -r 1b0b563a81e6 mcabber/doc/help/ru/hlp_move.txt
 --- a/mcabber/doc/help/ru/hlp_move.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/ru/hlp_move.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/ru/hlp_move.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,6 +1,7 @@
  
 - /MOVE [groupname]
@@ -1352,7 +1355,7 @@
  
 diff -r 1b0b563a81e6 mcabber/doc/help/ru/hlp_rename.txt
 --- a/mcabber/doc/help/ru/hlp_rename.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/ru/hlp_rename.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/ru/hlp_rename.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,6 @@
  
 - /RENAME name
@@ -1364,7 +1367,7 @@
 +Для указания обьекта, отличного от текущего, можно использовать опции --jid, --group и --name.
 diff -r 1b0b563a81e6 mcabber/doc/help/uk/hlp_buffer.txt
 --- a/mcabber/doc/help/uk/hlp_buffer.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/uk/hlp_buffer.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/uk/hlp_buffer.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -25,7 +25,7 @@
   Посунути буфер вверх на n рядків (якщо не вказано - пів екрану).
  /buffer down [n]
@@ -1376,7 +1379,7 @@
   Перейти до вказаної у процентах позиції.
 diff -r 1b0b563a81e6 mcabber/doc/help/uk/hlp_del.txt
 --- a/mcabber/doc/help/uk/hlp_del.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/uk/hlp_del.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/uk/hlp_del.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,4 @@
  
 - /DEL
@@ -1386,7 +1389,7 @@
 +Потерти поточний контакт (або контакт, що має вказаний jid) зі списку. Також відписатися від його сповіщень про статус і відписати його від ваших.
 diff -r 1b0b563a81e6 mcabber/doc/help/uk/hlp_move.txt
 --- a/mcabber/doc/help/uk/hlp_move.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/uk/hlp_move.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/uk/hlp_move.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,5 +1,6 @@
  
 - /MOVE [група]
@@ -1398,7 +1401,7 @@
  Примітка: в режимі розмови можна використати "/roster alternate", щоб перейти до нового місця контакту контакту.
 diff -r 1b0b563a81e6 mcabber/doc/help/uk/hlp_rename.txt
 --- a/mcabber/doc/help/uk/hlp_rename.txt	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/doc/help/uk/hlp_rename.txt	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/doc/help/uk/hlp_rename.txt	Sun Mar 24 00:58:15 2013 +0200
 @@ -1,4 +1,6 @@
  
 - /RENAME ім'я
@@ -1409,7 +1412,7 @@
 +Опції --jid, --group та --name дозволяють перейменовувати об’єкти, відмінні від поточного.
 diff -r 1b0b563a81e6 mcabber/mcabber/commands.c
 --- a/mcabber/mcabber/commands.c	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/mcabber/commands.c	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/mcabber/commands.c	Sun Mar 24 00:58:15 2013 +0200
 @@ -19,7 +19,7 @@
   * USA
   */
@@ -1463,11 +1466,11 @@
 +                 def_group,
 +                 def_say,
 +                 def_msay,
-+                 def_say_to;
-+#if 0
++                 def_say_to,
 +                 def_buffer,
 +                 def_clear,
-+                 def_info,
++                 def_info;
++#if 0
 +                 def_rename,
 +                 def_move,
 +                 def_set,
@@ -1580,10 +1583,10 @@
 +  cmd_list[7]  = &def_say;
 +  cmd_list[8]  = &def_msay;
 +  cmd_list[9]  = &def_say_to;
-+#if 0
 +  cmd_list[10] = &def_buffer;
 +  cmd_list[11] = &def_clear;
 +  cmd_list[12] = &def_info;
++#if 0
 +  cmd_list[13] = &def_rename;
 +  cmd_list[14] = &def_move;
 +  cmd_list[15] = &def_set;
@@ -2593,7 +2596,7 @@
    if (!*line) { // User only pressed enter
      if (scr_get_multimode()) {
        scr_append_multiline("");
-@@ -556,141 +725,585 @@
+@@ -556,141 +725,671 @@
      }
      if (current_buddy) {
        if (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_GROUP)
@@ -2711,15 +2714,8 @@
 +// + cmdarg_type_color
 +// + cmdarg_type_string2enum
 +// * cmdarg_type_nick        - provide completions first from current room, then from all other, nonspace, do not restrict
-+
-+//
-+//  generic destructors
-+//
-+
-+void cmdarg_free_gfree (cmdarg_value_t *arg)
-+{
-+  g_free (arg -> value.arg);
-+}
++// + cmdarg_type_filename    - expand, convert encoding
++// + cmdarg_type_date        - YYYYMMDDTHHMMSS -> time_t
 +
 +//
 +//  command environment checkers
@@ -2732,6 +2728,22 @@
 +  return NULL;
 +}
 +
++gchar *cmd_check_current_buddy (const cmdopts_t *command, cmdarg_value_t *values)
++{
++  if (!current_buddy)
++    return g_strdup ("No selected buddy!");
++  return NULL;
++}
++
++//
++//  generic value destructors
++//
++
++void cmdarg_free_gfree (cmdarg_value_t *arg)
++{
++  g_free (arg -> value.arg);
++}
++
 +//
 +//  string -> stripspace string
 +//
@@ -3250,6 +3262,83 @@
 +};
 +
 +//
++//  filename -> expanded local + utf8 filename
++//
++
++// Recognizes "~/" as $HOME.
++// Returns utf8 and converted to filesystem encoding file name in value.fname.
++// Requires freeing.
++// XXX:
++//  Should we convert filename at all?
++//   - it needs extra "big" type in values
++//   - it is not convenient to pass to function
++//   - utf8 version needs to be always freed
++//   - saves a bit of generic code, though.
++gchar *cmdarg_check_filename (cmdarg_value_t *value)
++{
++  gchar  *error;
++  GError *err   = NULL;
++
++  if ((error = cmdarg_check_nonspace(value)))
++    return error;
++
++  value -> value.fname.utf8  = expand_filename (value -> value.arg);
++  value -> value.fname.local = g_filename_from_utf8 (value -> value.fname.utf8,
++                                                          -1, NULL, NULL, &err);
++  if (err) {
++    value -> value.fname.utf8 = NULL;
++    error = g_strdup_printf ("Filename charset conversion error: %s",
++                                                                err -> message);
++    g_error_free (err);
++  } else {
++    value -> flags |= cmdval_freeme;
++  }
++
++  return error;
++}
++
++void cmdarg_free_fname (cmdarg_value_t *value)
++{
++  g_free (value -> value.fname.utf8);
++  g_free (value -> value.fname.local);
++}
++
++const cmdarg_type_t cmdarg_type_filename = {
++  cmdarg_check_color,
++  cmdarg_free_fname,
++  // TODO
++  NULL,
++};
++
++//
++//  ISO-8601 date -> epoch
++//
++
++// Converts "YYYYMMDD[(.|T)HH[:]MM[:]SS[.SSS][(+|-)HH:MM]" to epoch.
++// Returns epoch in value.time.
++// Needs no freeing.
++gchar *cmdarg_check_date (cmdarg_value_t *value)
++{
++  gchar  *error;
++  time_t epoch = 0;
++
++  if (!(error = cmdarg_check_nonspace (value))) {
++    epoch = from_iso8601 (value -> value.arg, 0);
++    if (!epoch)
++      error = g_strdup_printf ("Invalid date \"%s\".", value -> value.arg);
++  }
++
++  value -> value.time = epoch;
++  return error;
++}
++
++const cmdarg_type_t cmdarg_type_date = {
++  cmdarg_check_date,
++  NULL,
++  NULL,
++};
++
++//
 +//  Command definitions
 +//
 +// This section contains definitions for built-in mcabber commands.
@@ -3283,7 +3372,7 @@
  static void display_and_free_note(struct annotation *note, const char *winId)
  {
    gchar tbuf[128];
-@@ -755,41 +1368,15 @@
+@@ -755,41 +1454,15 @@
    g_slist_free(notes);
  }
  
@@ -3333,7 +3422,7 @@
      struct annotation *note = xmpp_get_storage_rosternotes(bjid, FALSE);
      if (note) {
        display_and_free_note(note, bjid);
-@@ -800,484 +1387,662 @@
+@@ -800,484 +1473,662 @@
    }
  }
  
@@ -4416,7 +4505,7 @@
  {
    char *bare_jid, *rp;
    char *hmsg;
-@@ -1285,6 +2050,7 @@
+@@ -1285,6 +2136,7 @@
    gint retval = 0;
    int isroom;
    gpointer xep184 = NULL;
@@ -4424,7 +4513,7 @@
  
    if (!xmpp_is_online()) {
      scr_LogPrint(LPRINT_NORMAL, "You are not connected.");
-@@ -1299,11 +2065,15 @@
+@@ -1299,11 +2151,15 @@
      return 1;
    }
    if (check_jid_syntax((char*)fjid)) {
@@ -4442,7 +4531,7 @@
    // We must use the bare jid in hk_message_out()
    rp = strchr(fjid, JID_RESOURCE_SEPARATOR);
    if (rp)
-@@ -1354,8 +2124,7 @@
+@@ -1354,8 +2210,7 @@
  //  send_message(msg, subj, type_overwrite)
  // Write the message in the buddy's window and send the message on
  // the network.
@@ -4452,7 +4541,7 @@
  {
    const char *bjid;
    char *jid;
-@@ -1378,34 +2147,13 @@
+@@ -1378,34 +2233,13 @@
    else
      jid = g_strdup(bjid);
  
@@ -4489,7 +4578,7 @@
  
    scr_set_chatmode(TRUE);
    scr_show_buddy_window();
-@@ -1424,135 +2172,195 @@
+@@ -1424,140 +2258,200 @@
    }
  
    buddy_setflags(bud, ROSTER_FLAG_LOCK, TRUE);
@@ -4779,16 +4868,22 @@
  //  load_message_from_file(filename)
  // Read the whole content of a file.
  // The data are converted to UTF8, they should be freed by the caller after
-@@ -1566,7 +2374,7 @@
+ // use.
+-char *load_message_from_file(const char *filename)
++char *load_message_from_file(const char *filename, const char *localfn)
+ {
+   FILE *fd;
+   struct stat buf;
+@@ -1566,7 +2460,7 @@
    char *next_utf8_char;
    size_t len;
  
 -  fd = fopen(filename, "r");
-+  fd = fopen(filename, "r"); // FIXME g_from_utf8
++  fd = fopen(localfn, "r");
  
    if (!fd || fstat(fileno(fd), &buf)) {
      scr_LogPrint(LPRINT_LOGNORM, "Cannot open message file (%s)", filename);
-@@ -1632,134 +2440,90 @@
+@@ -1632,273 +2526,314 @@
    return msgbuf_utf8;
  }
  
@@ -4804,7 +4899,7 @@
 +  pos_sayto_file    = 5,
 +} pos_sayto_t;
 +
-+cmdopts_t options = {
++static cmdopts_t def_say_to = {
 +  "say_to",
 +  cmd_default,
 +  cmd_check_online,
@@ -4911,7 +5006,7 @@
 +
 +  fjid = values[pos_sayto_jid].value.arg;
 +  msg  = values[pos_sayto_msg].value.arg;
-+  file = values[pos_sayto_file].value.arg;
++  file = values[pos_sayto_file].value.fname.utf8;
 +
 +  // XXX this is not yet in default fjid checker. should we add it there?
    if (!strchr(fjid, JID_DOMAIN_SEPARATOR)) {
@@ -4962,7 +5057,8 @@
 -    msg = msg_utf8 = load_message_from_file(filename_xp);
 -    g_free(filename_xp);
 -    g_free(file);
-+    freeme2 = msg = load_message_from_file(values[pos_sayto_file].value.arg);
++    freeme2 = msg = load_message_from_file(file,
++                                           values[pos_sayto_file].value.fname.local);
    }
  
 -  send_message_to(fjid, msg, NULL, msg_type, quiet);
@@ -4980,28 +5076,229 @@
 +  return NULL;
  }
  
-+#if 0
- //  buffer_updown(updown, nblines)
- // updown: -1=up, +1=down
- inline static void buffer_updown(int updown, char *nlines)
-@@ -1775,27 +2539,10 @@
-     scr_buffer_scroll_up_down(updown, nblines);
+-//  buffer_updown(updown, nblines)
+-// updown: -1=up, +1=down
+-inline static void buffer_updown(int updown, char *nlines)
++//
++//  /buffer
++//
++
++// argument type
++
++// Wrapper over uint to check maximum
++// XXX:
++//  * use chkdata in uint checker for that?
++static gchar *cmdarg_check_buffer_percent (cmdarg_value_t *value)
+ {
+-  int nblines;
+-
+-  if (!nlines || !*nlines)
+-    nblines = 0;
+-  else
+-    nblines = strtol(nlines, NULL, 10);
+-
+-  if (nblines >= 0)
+-    scr_buffer_scroll_up_down(updown, nblines);
++  gchar *error;
++
++  if (!(error = cmdarg_check_uint (value))) {
++    if (value -> value.uint > 100) {
++      error = g_strdup_printf ("Percent value %u is greater than 100.", value -> value.uint);
++      value -> value.uint = 0;
++    }
++  }
++
++  return error;
  }
  
 -static void buffer_search(int direction, char *arg)
--{
++static cmdarg_type_t cmdarg_type_buffer_percent = {
++  cmdarg_check_buffer_percent,
++  NULL,
++  NULL,
++};
++
++// command
++
++static gchar *do_buffer (const cmdopts_t *command, cmdarg_value_t *values);
++
++typedef enum {
++  scmd_buffer_close, scmd_buffer_close_all,
++  scmd_buffer_clear, scmd_buffer_purge,
++  scmd_buffer_list,
++  scmd_buffer_top, scmd_buffer_bottom, scmd_buffer_up, scmd_buffer_down,
++  scmd_buffer_date, scmd_buffer_percent, scmd_buffer_readmark,
++  scmd_buffer_search_backward, scmd_buffer_search_forward,
++  scmd_buffer_scroll_lock, scmd_buffer_scroll_unlock,
++  scmd_buffer_scroll_toggle,
++  scmd_buffer_save,
++} scmd_buffer_t;
++
++typedef enum {
++  pos_buffer_scmd      = 0,
++  pos_buffer_jid       = 1,
++  pos_buffer_n         = 1,
++  pos_buffer_date      = 1,
++  pos_buffer_percent   = 1,
++  pos_buffer_text      = 1,
++  pos_buffer_file      = 1,
++} pos_buffer_t;
++
++static cmdopts_t def_buffer = {
++  "buffer",
++  cmd_default,
++  cmd_check_current_buddy,
++  do_buffer,
++  NULL,
++  (cmdarg_t[2]){
++    { "subcommand", pos_buffer_scmd, cmdarg_subcmd|cmdarg_chreq, NULL, NULL },
++    {NULL},
++  },
++  (cmdopts_t[19]){
++    { "close", cmd_default, NULL, NULL, NULL,
++      (cmdarg_t[2]){
++        { "jid", pos_buffer_jid, cmdarg_required, NULL, &cmdarg_type_roster_bjid, (gpointer)(ROSTER_TYPE_USER|ROSTER_TYPE_ROOM|ROSTER_TYPE_AGENT|ROSTER_TYPE_SPECIAL) },
++        {NULL}
++      },
++      NULL, (gpointer)scmd_buffer_close },
++    { "close_all", cmd_default, NULL, NULL, NULL, NULL, NULL, (gpointer)scmd_buffer_close_all },
++    { "clear", cmd_default, NULL, NULL, NULL, NULL, NULL, (gpointer)scmd_buffer_clear },
++    { "purge", cmd_default, NULL, NULL, NULL,
++      (cmdarg_t[2]){
++        { "jid", pos_buffer_jid, cmdarg_required, NULL, &cmdarg_type_roster_bjid, (gpointer)(ROSTER_TYPE_USER|ROSTER_TYPE_ROOM|ROSTER_TYPE_AGENT|ROSTER_TYPE_SPECIAL) },
++        {0}
++      },
++      NULL, (gpointer)scmd_buffer_purge },
++    { "list", cmd_default, NULL, NULL, NULL, NULL, NULL, (gpointer)scmd_buffer_list },
++    { "top",    cmd_default, NULL, NULL, NULL, NULL, NULL, (gpointer)scmd_buffer_top    },
++    { "bottom", cmd_default, NULL, NULL, NULL, NULL, NULL, (gpointer)scmd_buffer_bottom },
++    { "up", cmd_default, NULL, NULL, NULL,
++      (cmdarg_t[2]){
++        { "n", pos_buffer_n, cmdarg_chreq, "0", &cmdarg_type_uint },
++        {NULL}
++      },
++      NULL, (gpointer)scmd_buffer_up },
++    { "down", cmd_default, NULL, NULL, NULL,
++      (cmdarg_t[2]){
++        { "n", pos_buffer_n, cmdarg_chreq, "0", &cmdarg_type_uint },
++        {NULL}
++      },
++      NULL, (gpointer)scmd_buffer_down },
++    { "date", cmd_default, NULL, NULL, NULL,
++      (cmdarg_t[2]){
++        { "date", pos_buffer_date, cmdarg_chreq, "1", &cmdarg_type_date },
++        {NULL}
++      },
++      NULL, (gpointer)scmd_buffer_date },
++    { "%", cmd_default, NULL, NULL, NULL,
++      (cmdarg_t[2]){
++        { "percent", pos_buffer_percent, cmdarg_chreq, "100", &cmdarg_type_buffer_percent },
++        {NULL}
++      },
++      NULL, (gpointer)scmd_buffer_percent },
++    { "readmark", cmd_default, NULL, NULL, NULL, NULL, NULL, (gpointer)scmd_buffer_readmark },
++    { "search_backward", cmd_default, NULL, NULL, NULL,
++      (cmdarg_t[2]){
++        { "text", pos_buffer_text, cmdarg_chreq, NULL, &cmdarg_type_nonspace },
++        {NULL}
++      },
++      NULL, (gpointer)scmd_buffer_search_backward },
++    { "search_forward", cmd_default, NULL, NULL, NULL,
++      (cmdarg_t[2]){
++        { "text", pos_buffer_text, cmdarg_chreq, NULL, &cmdarg_type_nonspace },
++        {NULL}
++      },
++      NULL, (gpointer)scmd_buffer_search_forward },
++    { "scroll_lock",   cmd_default, NULL, NULL, NULL, NULL, NULL, (gpointer)scmd_buffer_scroll_lock   },
++    { "scroll_unlock", cmd_default, NULL, NULL, NULL, NULL, NULL, (gpointer)scmd_buffer_scroll_unlock },
++    { "scroll_toggle", cmd_default, NULL, NULL, NULL, NULL, NULL, (gpointer)scmd_buffer_scroll_toggle },
++    { "save", cmd_default, NULL, NULL, NULL,
++      (cmdarg_t[2]){
++        { "filename", pos_buffer_file, cmdarg_chreq, NULL, &cmdarg_type_filename },
++        {NULL}
++      },
++      NULL, (gpointer)scmd_buffer_save },
++  },
++};
++
++// XXX % command before was able to handle %50
++static gchar *do_buffer (const cmdopts_t *command, cmdarg_value_t *values)
+ {
 -  if (!arg || !*arg) {
 -    scr_LogPrint(LPRINT_NORMAL, "Missing parameter.");
 -    return;
--  }
--
++  scmd_buffer_t subcmd = (scmd_buffer_t) (values[pos_buffer_scmd].value.cmd -> userdata);
++
++  if (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_GROUP &&
++      subcmd != scmd_buffer_close_all) {
++    return g_strdup ("Groups have no buffer.");
+   }
+ 
 -  scr_buffer_search(direction, arg);
--}
--
- static void buffer_date(char *date)
++  if (subcmd == scmd_buffer_close) {
++    scr_buffer_purge(1, buddy_getjid(values[pos_buffer_jid].value.rjid.bud));
++  } else if (subcmd == scmd_buffer_close_all) {
++    scr_buffer_purge_all(1);
++  } else if (subcmd == scmd_buffer_clear) {
++    scr_buffer_clear();
++  } else if (subcmd == scmd_buffer_purge) {
++    scr_buffer_purge(0, buddy_getjid(values[pos_buffer_jid].value.rjid.bud));
++  } else if (subcmd == scmd_buffer_list) {
++    scr_buffer_list();
++  } else if (subcmd == scmd_buffer_top) {
++    scr_buffer_top_bottom(-1);
++  } else if (subcmd == scmd_buffer_bottom) {
++    scr_buffer_top_bottom(1);
++  } else if (subcmd == scmd_buffer_up) {
++    scr_buffer_scroll_up_down(-1, values[pos_buffer_n].value.uint);
++  } else if (subcmd == scmd_buffer_down) {
++    scr_buffer_scroll_up_down(1, values[pos_buffer_n].value.uint);
++  } else if (subcmd == scmd_buffer_date) {
++    scr_buffer_date(values[pos_buffer_date].value.time);
++  } else if (subcmd == scmd_buffer_percent) {
++    scr_buffer_percent(values[pos_buffer_percent].value.uint);
++  } else if (subcmd == scmd_buffer_readmark) {
++    scr_buffer_jump_readmark();
++  } else if (subcmd == scmd_buffer_search_backward) {
++    scr_buffer_search(-1, values[pos_buffer_text].value.arg);
++  } else if (subcmd == scmd_buffer_search_forward) {
++    scr_buffer_search(1, values[pos_buffer_text].value.arg);
++  } else if (subcmd == scmd_buffer_scroll_lock) {
++    scr_buffer_scroll_lock(1);
++  } else if (subcmd == scmd_buffer_scroll_unlock) {
++    scr_buffer_scroll_lock(0);
++  } else if (subcmd == scmd_buffer_scroll_toggle) {
++    scr_buffer_scroll_lock(-1);
++  } else { // scmd_buffer_save
++    scr_buffer_dump(values[pos_buffer_file].value.fname.local);
++  }
++
++  return NULL;
+ }
+ 
+-static void buffer_date(char *date)
++//
++//  /clear
++//
++
++// XXX convert to real alias?
++static gchar *do_clear (const cmdopts_t *command, cmdarg_value_t *values);
++
++static cmdopts_t def_clear = {
++  "clear",
++  cmd_default,
++  cmd_check_current_buddy,
++  do_clear,
++  NULL,
++  NULL,
++  NULL,
++};
++
++// Alias for "buffer clear"
++static gchar *do_clear(const cmdopts_t *command, cmdarg_value_t *values)
  {
-   time_t t;
- 
+-  time_t t;
+-
 -  if (!date || !*date) {
 -    scr_LogPrint(LPRINT_NORMAL, "Missing parameter.");
 -    return;
@@ -5009,167 +5306,32 @@
 -
 -  strip_arg_special_chars(date);
 -
-   t = from_iso8601(date, 0);
-   if (t)
-     scr_buffer_date(t);
-@@ -1804,98 +2551,156 @@
-                  "not correctly formatted or invalid.");
+-  t = from_iso8601(date, 0);
+-  if (t)
+-    scr_buffer_date(t);
+-  else
+-    scr_LogPrint(LPRINT_NORMAL, "The date you specified is "
+-                 "not correctly formatted or invalid.");
++  scr_buffer_clear();
++  return NULL;
  }
  
 -static void buffer_percent(char *arg1, char *arg2)
-+// XXX % command before was able to handle %50
-+static void do_buffer(char *arg)
- {
+-{
 -  // Basically, user has typed "%arg1 arg2"
 -  // "%50"  -> arg1 = 50, arg2 null pointer
 -  // "% 50" -> arg1 = \0, arg2 = 50
 -
 -  if (!*arg1 && (!arg2 || !*arg2)) { // No value
 -    scr_LogPrint(LPRINT_NORMAL, "Missing parameter.");
-+  enum buffer_scmd_t {
-+    buffer_scmd_close, buffer_scmd_close_all,
-+    buffer_scmd_clear, buffer_scmd_purge,
-+    buffer_scmd_list,
-+    buffer_scmd_top, buffer_scmd_bottom, buffer_scmd_up, buffer_scmd_down,
-+    buffer_scmd_date, buffer_scmd_percent, buffer_scmd_readmark,
-+    buffer_scmd_search_backward, buffer_scmd_search_forward,
-+    buffer_scmd_scroll_lock, buffer_scmd_scroll_unlock,
-+    buffer_scmd_scroll_toggle,
-+    buffer_scmd_save,
-+  } subcmd;
-+  cmdopts_t options = {
-+    "buffer",
-+    NULL,
-+    (cmdarg_t[1]){
-+      { CMDOPT_REQUIRED | CMDOPT_SUBCOMMAND | CMDOPT_LAST, { .cmd = NULL } },
-+    },
-+    (cmdopts_t[18]){
-+      { "close",
-+        (cmdopt_t[1]){
-+          { CMDOPT_SWITCH | CMDOPT_LAST, 'a', "all", { .swc = 0 } }
-+        },
-+        (cmdarg_t[1]){
-+          { CMDOPT_LAST, { .cmd = NULL } } // jid
-+        },
-+        NULL, (gpointer)buffer_scmd_close, 0 },
-+      { "close_all", NULL, NULL, NULL, (gpointer)buffer_scmd_close_all, 0 },
-+      { "clear", NULL, NULL, NULL, (gpointer)buffer_scmd_clear, 0 },
-+      { "purge", NULL,
-+        (cmdarg_t[1]){
-+          { CMDOPT_LAST, { .arg = NULL } }, // jid
-+        },
-+        NULL, (gpointer)buffer_scmd_purge, 0 },
-+      { "list", NULL, NULL, NULL, (gpointer)buffer_scmd_list, 0 },
-+      { "top", NULL, NULL, NULL, (gpointer)buffer_scmd_top, 0 },
-+      { "bottom", NULL, NULL, NULL, (gpointer)buffer_scmd_bottom, 0 },
-+      { "up", NULL,
-+        (cmdarg_t[1]){
-+          { CMDOPT_LAST, { .arg = NULL } }, // lines
-+        },
-+        NULL, (gpointer)buffer_scmd_up, 0 },
-+      { "down", NULL,
-+        (cmdarg_t[1]){
-+          { CMDOPT_LAST, { .arg = NULL } }, // lines
-+        },
-+        NULL, (gpointer)buffer_scmd_down, 0 },
-+      { "date", NULL,
-+        (cmdarg_t[1]){
-+          // date
-+          { CMDOPT_CATCHALL | CMDOPT_REQUIRED | CMDOPT_LAST, { .arg = "1" } },
-+        },
-+        NULL, (gpointer)buffer_scmd_date, 0 },
-+      { "%", NULL,
-+        (cmdarg_t[1]){
-+          { CMDOPT_REQUIRED | CMDOPT_LAST, { .arg = "100" } }, // percent
-+        },
-+        NULL, (gpointer)buffer_scmd_percent, 0 },
-+      { "readmark", NULL, NULL, NULL, (gpointer)buffer_scmd_readmark, 0 },
-+      { "search_backward", NULL,
-+        (cmdarg_t[1]){
-+          { CMDOPT_REQUIRED | CMDOPT_CATCHALL | CMDOPT_LAST,
-+            { .arg = NULL } },
-+        },
-+        NULL, (gpointer)buffer_scmd_search_backward, 0 },
-+      { "search_forward", NULL,
-+        (cmdarg_t[1]){
-+          { CMDOPT_REQUIRED | CMDOPT_CATCHALL | CMDOPT_LAST,
-+            { .arg = NULL } },
-+        },
-+        NULL, (gpointer)buffer_scmd_search_forward, 0 },
-+      { "scroll_lock", NULL, NULL, NULL,
-+        (gpointer)buffer_scmd_scroll_lock, 0 },
-+      { "scroll_unlock", NULL, NULL, NULL,
-+        (gpointer)buffer_scmd_scroll_unlock, 0 },
-+      { "scroll_toggle", NULL, NULL, NULL,
-+        (gpointer)buffer_scmd_scroll_toggle, 0 },
-+      { "save", NULL,
-+        (cmdarg_t[1]){
-+          { CMDOPT_REQUIRED | CMDOPT_CATCHALL | CMDOPT_PLAIN | CMDOPT_LAST,
-+            { .arg = NULL } },
-+        },
-+        NULL, (gpointer)buffer_scmd_save, CMDOPT_LAST },
-+    },
-+  };
-+
-+  if (!current_buddy)
-+    return;
-+
-+  if (cmdopts_parse(arg, &options))
-+    return;
-+
-+  subcmd = (enum buffer_scmd_t) options.args[0].value.cmd -> userdata;
-+
-+  if (subcmd == buffer_scmd_close && options.cmds[0].opts[0].value.swc)
-+    subcmd = buffer_scmd_close_all;
-+
-+  if (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_GROUP &&
-+      subcmd != buffer_scmd_close_all) {
-+    scr_LogPrint(LPRINT_NORMAL, "Groups have no buffer.");
-+    cmdopts_free(&options);
-     return;
-   }
- 
+-    return;
+-  }
+-
 -  if (*arg1 && arg2 && *arg2) {     // Two values
 -    scr_LogPrint(LPRINT_NORMAL, "Wrong parameters.");
 -    return;
-+  if (subcmd == buffer_scmd_close) {
-+    scr_buffer_purge(1, options.cmds[0].args[0].value.arg);
-+  } else if (subcmd == buffer_scmd_close_all) {
-+    scr_buffer_purge_all(1);
-+  } else if (subcmd == buffer_scmd_clear) {
-+    scr_buffer_clear();
-+  } else if (subcmd == buffer_scmd_purge) {
-+    scr_buffer_purge(0, options.cmds[3].args[0].value.arg);
-+  } else if (subcmd == buffer_scmd_list) {
-+    scr_buffer_list();
-+  } else if (subcmd == buffer_scmd_top) {
-+    scr_buffer_top_bottom(-1);
-+  } else if (subcmd == buffer_scmd_bottom) {
-+    scr_buffer_top_bottom(1);
-+  } else if (subcmd == buffer_scmd_up) {
-+    buffer_updown(-1, options.cmds[7].args[0].value.arg);
-+  } else if (subcmd == buffer_scmd_down) {
-+    buffer_updown(1, options.cmds[8].args[0].value.arg);
-+  } else if (subcmd == buffer_scmd_date) {
-+    buffer_date(options.cmds[9].args[0].value.arg);
-+  } else if (subcmd == buffer_scmd_percent) {
-+    scr_buffer_percent(atoi(options.cmds[10].args[0].value.arg));
-+  } else if (subcmd == buffer_scmd_readmark) {
-+    scr_buffer_jump_readmark();
-+  } else if (subcmd == buffer_scmd_search_backward) {
-+    scr_buffer_search(-1, options.cmds[12].args[0].value.arg);
-+  } else if (subcmd == buffer_scmd_search_forward) {
-+    scr_buffer_search(1, options.cmds[13].args[0].value.arg);
-+  } else if (subcmd == buffer_scmd_scroll_lock) {
-+    scr_buffer_scroll_lock(1);
-+  } else if (subcmd == buffer_scmd_scroll_unlock) {
-+    scr_buffer_scroll_lock(0);
-+  } else if (subcmd == buffer_scmd_scroll_toggle) {
-+    scr_buffer_scroll_lock(-1);
-+  } else { // buffer_scmd_save
-+    scr_buffer_dump(options.cmds[17].args[0].value.arg);
-   }
- 
+-  }
+-
 -  scr_buffer_percent(atoi((*arg1 ? arg1 : arg2)));
 -}
 -
@@ -5241,20 +5403,54 @@
 -  }
 -
 -  free_arg_lst(paramlst);
-+  cmdopts_free(&options);
- }
- 
- static void do_clear(char *arg)    // Alias for "buffer clear"
- {
+-}
+-
+-static void do_clear(char *arg)    // Alias for "buffer clear"
+-{
 -  do_buffer("clear");
-+  scr_buffer_clear();
+-}
+-
+-static void do_info(char *arg)
++//
++//  /info
++//
++
++static gchar *do_info (const cmdopts_t *command, cmdarg_value_t *values);
++
++static cmdopts_t def_info = {
++  "clear",
++  cmd_default,
++  cmd_check_current_buddy,
++  do_info,
++  NULL,
++  NULL,
++  NULL,
++};
++
++static gchar *do_info (const cmdopts_t *command, cmdarg_value_t *values)
+ {
+   gpointer bud;
+   const char *bjid, *name;
+@@ -1906,9 +2841,7 @@
+   char *buffer;
+   enum subscr esub;
+ 
+-  if (!current_buddy)
+-    return;
+-  bud = BUDDATA(current_buddy);
++  bud    = BUDDATA(current_buddy);
+ 
+   bjid   = buddy_getjid(bud);
+   name   = buddy_getname(bud);
+@@ -2031,31 +2964,25 @@
+                                HBB_PREFIX_INFO, 0);
+     }
+   }
++
++  return NULL;
  }
  
- static void do_info(char *arg)
-@@ -2033,29 +2838,20 @@
-   }
- }
- 
++#if 0
 +enum room_names_style_t {
 +  room_names_style_normal = 0,
 +  room_names_style_detail,
@@ -5290,7 +5486,7 @@
  
    // Enter chat mode
    scr_set_chatmode(TRUE);
-@@ -2075,12 +2871,12 @@
+@@ -2075,12 +3002,12 @@
      rstatus = buddy_getstatus(bud, p_res->data);
      rst_msg = buddy_getstatusmsg(bud, p_res->data);
  
@@ -5305,7 +5501,7 @@
          enum imrole role = buddy_getrole(bud, p_res->data);
          enum imaffiliation affil = buddy_getaffil(bud, p_res->data);
          bool showaffil = (affil != affil_none);
-@@ -2096,12 +2892,12 @@
+@@ -2096,12 +3023,12 @@
        snprintf(buffer, 4095, "[%c] %s", imstatus2char[rstatus],
                 (char*)p_res->data);
        scr_WriteIncomingMessage(bjid, buffer, 0, HBB_PREFIX_INFO, 0);
@@ -5320,7 +5516,7 @@
          enum imrole role = buddy_getrole(bud, p_res->data);
          enum imaffiliation affil = buddy_getaffil(bud, p_res->data);
  
-@@ -2145,16 +2941,69 @@
+@@ -2145,16 +3072,69 @@
  
  static void do_rename(char *arg)
  {
@@ -5395,7 +5591,7 @@
    bjid   = buddy_getjid(bud);
    group  = buddy_getgroupname(bud);
    type   = buddy_gettype(bud);
-@@ -2162,11 +3011,13 @@
+@@ -2162,11 +3142,13 @@
  
    if (type & ROSTER_TYPE_SPECIAL) {
      scr_LogPrint(LPRINT_NORMAL, "You can't rename this item.");
@@ -5410,7 +5606,7 @@
      return;
    }
  
-@@ -2181,90 +3032,117 @@
+@@ -2181,90 +3163,117 @@
    //  }
    //}
  
@@ -5559,7 +5755,7 @@
      } else {
        // This is a local item, we move it without adding to roster.
        guint msgflag;
-@@ -2276,7 +3154,7 @@
+@@ -2276,7 +3285,7 @@
        msgflag = buddy_getflags(bud) & ROSTER_FLAG_MSG;
        if (msgflag)
          roster_msg_setflag(bjid, FALSE, FALSE);
@@ -5568,7 +5764,7 @@
        if (msgflag)
          roster_msg_setflag(bjid, FALSE, TRUE);
        if ((type & ROSTER_TYPE_ROOM) && xmpp_is_bookmarked(bjid) &&
-@@ -2285,8 +3163,7 @@
+@@ -2285,8 +3294,7 @@
      }
    }
  
@@ -5578,7 +5774,7 @@
    update_roster = TRUE;
  }
  
-@@ -2468,50 +3345,33 @@
+@@ -2468,50 +3476,33 @@
  
  static void do_rawxml(char *arg)
  {
@@ -5649,7 +5845,7 @@
  }
  
  //  check_room_subcommand(arg, param_needed, buddy_must_be_a_room)
-@@ -2815,6 +3675,8 @@
+@@ -2815,6 +3806,8 @@
    free_arg_lst(paramlst);
  }
  
@@ -5658,7 +5854,7 @@
  void cmd_room_leave(gpointer bud, char *arg)
  {
    gchar *roomid, *desc;
-@@ -2833,6 +3695,8 @@
+@@ -2833,6 +3826,8 @@
    g_free(roomid);
  }
  
@@ -5667,7 +5863,7 @@
  static void room_nick(gpointer bud, char *arg)
  {
    if (!buddy_getinsideroom(bud)) {
-@@ -2874,7 +3738,7 @@
+@@ -2874,7 +3869,7 @@
    fjid_utf8 = g_strdup_printf("%s/%s", buddy_getjid(bud), nick_utf8);
    g_free (nick_utf8);
    msg = to_utf8(arg);
@@ -5676,7 +5872,7 @@
    g_free(fjid_utf8);
    g_free(msg);
    free_arg_lst(paramlst);
-@@ -3052,6 +3916,8 @@
+@@ -3052,6 +4047,8 @@
    free_arg_lst(paramlst);
  }
  
@@ -5685,7 +5881,7 @@
  //  cmd_room_whois(..)
  // If interactive is TRUE, chatmode can be enabled.
  // Please note that usernick is expected in UTF-8 locale iff interactive is
-@@ -3146,6 +4012,8 @@
+@@ -3146,6 +4143,8 @@
      free_arg_lst(paramlst);
  }
  
@@ -5694,7 +5890,7 @@
  static void room_bookmark(gpointer bud, char *arg)
  {
    const char *roomid;
-@@ -3290,6 +4158,207 @@
+@@ -3290,6 +4289,207 @@
  
  static void do_room(char *arg)
  {
@@ -5902,7 +6098,7 @@
    char **paramlst;
    char *subcmd;
    gpointer bud;
-@@ -3347,7 +4416,7 @@
+@@ -3347,7 +4547,7 @@
        cmd_room_leave(bud, arg);
    } else if (!strcasecmp(subcmd, "names"))  {
      if ((arg = check_room_subcommand(arg, FALSE, bud)) != NULL)
@@ -5911,7 +6107,7 @@
    } else if (!strcasecmp(subcmd, "nick"))  {
      if ((arg = check_room_subcommand(arg, FALSE, bud)) != NULL)
        room_nick(bud, arg);
-@@ -4162,5 +5231,6 @@
+@@ -4162,5 +5362,6 @@
    }
    mcabber_set_terminate_ui();
  }
@@ -5920,8 +6116,8 @@
  /* vim: set expandtab cindent cinoptions=>2\:2(0 sw=2 ts=2:  For Vim users... */
 diff -r 1b0b563a81e6 mcabber/mcabber/commands.h
 --- a/mcabber/mcabber/commands.h	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/mcabber/commands.h	Sat Mar 23 03:59:57 2013 +0200
-@@ -5,32 +5,346 @@
++++ b/mcabber/mcabber/commands.h	Sun Mar 24 00:58:15 2013 +0200
+@@ -5,32 +5,362 @@
  
  #include <mcabber/config.h>
  
@@ -5980,6 +6176,9 @@
 +//   - xmpp_is_online()
 +//   - current_buddy
 +// * Usable subsystem for completion, based on user-supplied completors
++// * commands:
++//   - say/msay/say_to/room privmsg/process_line() - sort things out, maybe write special argchecker
++//   - buffer close now only accepts windows with jid. additional checker, that also allows current 'status' buffer?
 +//
 +//  XXX:
 +//
@@ -6122,6 +6321,11 @@
 +      gpointer      bud;         //   - buddy struct
 +      gchar         *resource;   //   - resource (optional)
 +    } rjid;                      // 
++    struct {                     // - filename
++      gchar         *utf8;       //   - in utf8
++      gchar         *local;      //   - in local FS encoding
++    } fname;                     //
++    time_t          time;        // - date/time
 +    gpointer        ptr;         // - anything else
 +  } value;                       //
 +};
@@ -6231,6 +6435,12 @@
 +gchar *cmdarg_check_string2enum     (cmdarg_value_t *arg);
 +// checks mcabber color name syntax
 +gchar *cmdarg_check_color           (cmdarg_value_t *arg);
++// expands filename and converts encoding
++gchar *cmdarg_check_filename        (cmdarg_value_t *arg);
++// destructor, frees both names
++void cmdarg_free_fname              (cmdarg_value_t *arg);
++// converts iso-8601 date to epoch
++gchar *cmdarg_check_date            (cmdarg_value_t *arg);
 +
 +// ready for use standard type descriptions
 +const cmdarg_type_t cmdarg_type_nonspace;
@@ -6243,6 +6453,8 @@
 +const cmdarg_type_t cmdarg_type_charset;
 +const cmdarg_type_t cmdarg_type_string2enum;
 +const cmdarg_type_t cmdarg_type_color;
++const cmdarg_type_t cmdarg_type_filename;
++const cmdarg_type_t cmdarg_type_date;
 +
 +//
 +//  Private
@@ -6290,7 +6502,7 @@
  
 diff -r 1b0b563a81e6 mcabber/mcabber/hooks.c
 --- a/mcabber/mcabber/hooks.c	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/mcabber/hooks.c	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/mcabber/hooks.c	Sun Mar 24 00:58:15 2013 +0200
 @@ -638,10 +638,9 @@
  
    scr_LogPrint(LPRINT_LOGNORM, "Running hook-post-connect...");
@@ -6319,7 +6531,7 @@
  
 diff -r 1b0b563a81e6 mcabber/mcabber/roster.c
 --- a/mcabber/mcabber/roster.c	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/mcabber/roster.c	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/mcabber/roster.c	Sun Mar 24 00:58:15 2013 +0200
 @@ -1586,13 +1586,14 @@
  // Look for a buddy whose name or jid contains string.
  // Search begins at current_buddy; if no match is found in the the buddylist,
@@ -6360,7 +6572,7 @@
      }
 diff -r 1b0b563a81e6 mcabber/mcabber/screen.c
 --- a/mcabber/mcabber/screen.c	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/mcabber/screen.c	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/mcabber/screen.c	Sun Mar 24 00:58:15 2013 +0200
 @@ -3630,7 +3630,7 @@
  {
    scr_check_auto_away(TRUE);
@@ -6430,7 +6642,7 @@
    }
 diff -r 1b0b563a81e6 mcabber/mcabber/settings.c
 --- a/mcabber/mcabber/settings.c	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/mcabber/settings.c	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/mcabber/settings.c	Sun Mar 24 00:58:15 2013 +0200
 @@ -183,28 +183,12 @@
      if ((*line == '\n') || (*line == '\0') || (*line == '#'))
        continue;
@@ -6467,7 +6679,7 @@
    fclose(fp);
 diff -r 1b0b563a81e6 mcabber/mcabber/xmpp_iq.c
 --- a/mcabber/mcabber/xmpp_iq.c	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/mcabber/xmpp_iq.c	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/mcabber/xmpp_iq.c	Sun Mar 24 00:58:15 2013 +0200
 @@ -71,20 +71,20 @@
  struct adhoc_status {
    char *name;   // the name used by adhoc
@@ -6516,7 +6728,7 @@
                                                "Status has been changed");
 diff -r 1b0b563a81e6 mcabber/modules/beep/beep.c
 --- a/mcabber/modules/beep/beep.c	Wed Mar 13 16:11:16 2013 +0200
-+++ b/mcabber/modules/beep/beep.c	Sat Mar 23 03:59:57 2013 +0200
++++ b/mcabber/modules/beep/beep.c	Sun Mar 24 00:58:15 2013 +0200
 @@ -31,6 +31,7 @@
  
  static void beep_init   (void);