mirror of
https://github.com/irssi/irssi.git
synced 2026-08-08 19:30:15 +02:00
[2025-08-24 21:00:15] Inicjalizacja kolejnej próby - przywrócenie dokumentacji i plików roboczych
This commit is contained in:
parent
4f8ef0ccb7
commit
4032558538
5 changed files with 785 additions and 39 deletions
|
|
@ -166,26 +166,32 @@ Fundamentalny konflikt:
|
|||
2. **Wymóg kolorów**: Tryb i nick potrzebują osobnego formatowania kolorów z abstrakcji motywu
|
||||
3. **Obecne ograniczenie**: Po połączeniu w C, motyw widzi pojedynczy string i nie może zastosować osobnych kolorów
|
||||
|
||||
## HISTORIA PRÓB IMPLEMENTACJI
|
||||
|
||||
### PRÓBA 1: Parse Special + ALIGN_COMBINE_MODE (2025-01-24)
|
||||
**Podejście**: Modyfikacja `parse_special()` z flagą `&` do łączenia mode+nick przed wyrównaniem.
|
||||
**Problem**: Ograniczenie interpretacji kolorów - po połączeniu mode+nick w jeden string, theme nie może zastosować osobnych kolorów.
|
||||
**Status**: ❌ Niepowodzenie
|
||||
|
||||
### PRÓBA 2: Expandos bez kontekstu (wcześniej)
|
||||
**Podejście**: Tworzenie expandos `nick_with_mode`, `nick_padding` itp.
|
||||
**Problem**: Expandos nie mają dostępu do `arglist` z formatowania - zwracają puste stringi.
|
||||
**Status**: ❌ Niepowodzenie
|
||||
|
||||
### PRÓBA 3: Modyfikacja format_get_text_args (2025-01-24)
|
||||
**Podejście**: Wstrzyknięcie dodatkowego parametru padding do `arglist` w `format_get_text_args()`.
|
||||
**Problem**: Błędna analiza argumentów - myślałem że `$0=nick`, ale `$0=mode`, `$1=nick`. Przesuwanie argumentów psuło mapowanie.
|
||||
**Status**: ❌ Niepowodzenie - fundamentalnie błędne założenia
|
||||
|
||||
### WNIOSKI Z NIEPOWODZEŃ:
|
||||
1. **Modyfikacja argumentów formatowania jest ryzykowna** - łatwo zepsuć istniejące mapowanie
|
||||
2. **Expandos bez kontekstu nie działają** - potrzebują dostępu do aktualnych danych message
|
||||
3. **Analiza flow musi być dokładna** - błędne założenia prowadzą do niefunkcjonalnych rozwiązań
|
||||
|
||||
## AKTUALNE USTALENIA (2025-01-24)
|
||||
|
||||
### Analiza Flow Wiadomości
|
||||
Przeprowadzono szczegółową analizę flow wiadomości w Irssi od otrzymania z serwera do wyświetlenia (dokumentacja w `msg_flow.md`). Zidentyfikowano fundamentalny problem z podejściem expandos.
|
||||
### Rekomendowane Rozwiązanie: Expandos z kontekstem sygnałów
|
||||
**INSPIRACJA**: Skrypt nm2.pl pokazuje właściwe podejście - expandos + sygnały + dynamiczne przepisywanie formatów.
|
||||
|
||||
### Problem z Expandos
|
||||
Expandos nie mają dostępu do `arglist` z formatowania - są wywoływane globalnie bez kontekstu lokalnego formatowania. To powoduje, że zwracają puste stringi zamiast rzeczywistych wartości mode i nick.
|
||||
|
||||
### Rekomendowane Rozwiązanie
|
||||
**Rozszerzenie systemu wyrównania w `parse_special`** zamiast expandos:
|
||||
|
||||
1. **Nowa składnia**: `$[~&nick_column]0` - wyrównanie z flagą nick_column
|
||||
2. **Zachowuje osobne parametry** - mode ($0) i nick ($1) pozostają oddzielne dla kolorowania
|
||||
3. **Zgodne z roadmapą Irssi** - "variable/dynamic expandos with arguments"
|
||||
4. **Eleganckie kodowo** - rozszerza istniejący system zamiast go obchodzić
|
||||
|
||||
### Wymagania Implementacji
|
||||
|
||||
- Rozszerzyć `get_alignment_args()` o flagę `&nick_column`
|
||||
- Dodać `ALIGN_NICK_COLUMN` do special-vars.h
|
||||
- Implementować logikę kombinowania mode+nick przed wyrównaniem
|
||||
- Zachować osobne parametry po wyrównaniu dla theme
|
||||
- Ustawienia: `nick_column_enabled` i `nick_column_width`
|
||||
**KLUCZOWA IDEA**:
|
||||
Zamiast modyfikować argumenty, stworzyć expando który zwraca gotowy string z paddingiem, mode i nickiem.
|
||||
|
|
|
|||
569
nm2.pl
Normal file
569
nm2.pl
Normal file
|
|
@ -0,0 +1,569 @@
|
|||
use Irssi;
|
||||
use strict;
|
||||
use v5.14;
|
||||
use List::Util qw(min max);
|
||||
use Hash::Util qw(lock_keys);
|
||||
|
||||
our $VERSION = '2.1'; # a42b713aaa38823
|
||||
our %IRSSI = (
|
||||
authors => 'Nei',
|
||||
contact => 'Nei @ anti@conference.jabber.teamidiot.de',
|
||||
url => "http://anti.teamidiot.de/",
|
||||
name => 'nm2',
|
||||
description => 'right aligned nicks depending on longest nick',
|
||||
license => 'GPL v2',
|
||||
);
|
||||
|
||||
# based on bc-bd's original nm.pl
|
||||
#
|
||||
# use a ** nickcolor_expando ** script for nick colors!
|
||||
#
|
||||
# why is there no right_mode? you can do that in your theme!
|
||||
|
||||
# Options
|
||||
# =======
|
||||
# /set neat_dynamic <ON|OFF>
|
||||
# * whether the width should be dynamically chosen on each incoming
|
||||
# message
|
||||
#
|
||||
# /set neat_shrink <ON|OFF>
|
||||
# * whether shrinking of the width is allowed, or only growing
|
||||
#
|
||||
# /set neat_staircase_shrink <ON|OFF>
|
||||
# * whether shrinking should be done one character at a time
|
||||
#
|
||||
# The following styles decide if the nick is left/right aligned and
|
||||
# where the colour/mode goes, they're a bit complex...
|
||||
# put the desired indicator(s) between the appropriate "," and the
|
||||
# default format of the public messages or actions will be rewritten
|
||||
# appropriately.
|
||||
# This can be used to align the nick left or right, before or after
|
||||
# the nick brackets and before or between the nickmode (by using the
|
||||
# pad on the correct place). To change the mode from left of the nick
|
||||
# to right of the nick, you need to modify the abstracts in your theme
|
||||
# however.
|
||||
# By placing the colour at the end, you can even colour the message
|
||||
# text in the nick colour, however it might be broken if there are
|
||||
# other colour codes used inside the message or by scripts.
|
||||
#
|
||||
# /format neat_style , , , , , , , ,
|
||||
# î î î î î î î î î
|
||||
# p: pad | | | | | | | | `before message
|
||||
# c: colour | | | | | | | `-after msgchannel
|
||||
# t: truncate indicator | | | | | | `-before msgchannel
|
||||
# | | | | | `-after nick
|
||||
# | | | | `-before nick
|
||||
# | | | `-after mode
|
||||
# | | `-before mode
|
||||
# | `-before msgnick
|
||||
# `-none
|
||||
#
|
||||
# /format neat_action_style , , , ,
|
||||
# î î î î î
|
||||
# p: pad | | | | `-before message
|
||||
# c: colour | | | `-after nick
|
||||
# t: truncate indicator | | `-before nick
|
||||
# | `-before action
|
||||
# `-none
|
||||
#
|
||||
# /format neat_pad_char <char>
|
||||
# * the character(s) used for padding
|
||||
#
|
||||
# /format neat_truncate_char
|
||||
# * the format or character to indicate that nick was truncated
|
||||
#
|
||||
# /format neat_notruncate_char
|
||||
# * the format or character to indicate that nick NOT was truncated
|
||||
#
|
||||
# /format neat_customize_modes @@ | ++ | ?
|
||||
# * a |-separated mapping of mode prefixes and their rendition, can be
|
||||
# used to replace or colourise them
|
||||
#
|
||||
# /set neat_color_hinick <ON|OFF>
|
||||
# * whether to use colours in hilighted messages
|
||||
#
|
||||
# /set neat_color_menick <ON|OFF>
|
||||
# * whether to use colours in hilight_nick_matches
|
||||
#
|
||||
# /set neat_truncate_nick <ON|OFF>
|
||||
# * whether to truncate overlong nicks
|
||||
#
|
||||
# /set neat_custom_modes <ON|OFF>
|
||||
# * whether to enable the use of neat_customize_modes format
|
||||
#
|
||||
# /set neat_maxlength <number>
|
||||
# * number : (maximum) length to use for nick padding
|
||||
#
|
||||
# /set neat_melength <number>
|
||||
# * number : width to substract from maxlength for /me padding
|
||||
#
|
||||
# /set neat_history <number>
|
||||
# * number : number of formatted lines to remember for dynamic mode
|
||||
#
|
||||
|
||||
my @action_protos = qw(irc silc xmpp);
|
||||
my (%histories, %S, @style, @astyle, %format_ok, %cmmap);
|
||||
|
||||
my $align_expando = '';
|
||||
my $trunc_expando = '';
|
||||
my $cumode_expando = '';
|
||||
|
||||
my $format_re = qr/ %(?=[}%{])
|
||||
| %[04261537kbgcrmywKBGCRMYWU9_8I:|FnN>#pP[]
|
||||
| %[Zz][[:xdigit:]]{6}
|
||||
| %[Xx](?i:0[a-f]|[1-6][0-9a-z]|7[a-x]) /x;
|
||||
|
||||
sub update_expando {
|
||||
my ($mode, $server, $target, $nick, $space) = @_;
|
||||
my $t_add;
|
||||
if (exists $Irssi::Script::{'realnames::'}
|
||||
&& (my $code = 'Irssi::Script::realnames'->can('_get_nick_chan'))) {
|
||||
if (my $i = $code->($server, $target, $nick)) {
|
||||
$nick = $i->{n}{realname}
|
||||
if length $i->{n}{realname};
|
||||
}
|
||||
}
|
||||
my $nl = length $nick;
|
||||
my $pad_len = max(0, $space - $nl);
|
||||
if ($S{truncate_nick}) {
|
||||
if (($mode >= 4 && $S{trunc_in_anick})
|
||||
|| ($mode < 4 && $S{trunc_in_nick})) {
|
||||
$t_add = $S{tnolen};
|
||||
}
|
||||
if ($nl + $t_add > $space) {
|
||||
$trunc_expando = format_expand($S{tyes_char});
|
||||
$t_add = $S{tyeslen} if defined $t_add;
|
||||
}
|
||||
else {
|
||||
$trunc_expando = format_expand($S{tno_char});
|
||||
}
|
||||
$pad_len = max(0, $pad_len - $t_add) if $t_add;
|
||||
}
|
||||
else {
|
||||
$trunc_expando = '';
|
||||
}
|
||||
if ($pad_len) {
|
||||
my @subs = split /($format_re)/, $S{pad_char} x $pad_len;
|
||||
$align_expando = '';
|
||||
my $clen = 0;
|
||||
while (@subs) {
|
||||
my ($tx, $fmt) = splice @subs, 0, 2;
|
||||
my $txlen = length $tx // 0;
|
||||
$align_expando .= substr $tx, 0, ($pad_len - $clen) if defined $tx;
|
||||
$clen += $txlen;
|
||||
$align_expando .= $fmt if defined $fmt;
|
||||
last if $clen >= $pad_len;
|
||||
}
|
||||
$align_expando = format_expand($align_expando.'%n');
|
||||
}
|
||||
else {
|
||||
$align_expando = '';
|
||||
}
|
||||
return $t_add;
|
||||
}
|
||||
|
||||
sub prnt_clear_levels {
|
||||
my ($dest) = @_;
|
||||
clear_ref() if $dest->{level}
|
||||
& (MSGLEVEL_PUBLIC|MSGLEVEL_MSGS|MSGLEVEL_ACTIONS|MSGLEVEL_DCCMSGS|MSGLEVEL_NOTICES);
|
||||
}
|
||||
|
||||
sub clear_ref {
|
||||
$trunc_expando = $align_expando = $cumode_expando = '';
|
||||
}
|
||||
|
||||
sub expando_nickalign { $align_expando }
|
||||
sub expando_nicktrunc { $trunc_expando }
|
||||
sub expando_nickcumode { $cumode_expando }
|
||||
|
||||
Irssi::expando_create('nickalign', \&expando_nickalign, {
|
||||
'message public' => 'none',
|
||||
'message own_public' => 'none',
|
||||
'message private' => 'none',
|
||||
'message own_private' => 'none',
|
||||
(map { ("message $_ action" => 'none',
|
||||
"message $_ own_action" => 'none')
|
||||
} @action_protos),
|
||||
});
|
||||
Irssi::expando_create('nicktrunc', \&expando_nicktrunc, {
|
||||
'message public' => 'none',
|
||||
'message own_public' => 'none',
|
||||
'message private' => 'none',
|
||||
'message own_private' => 'none',
|
||||
(map { ("message $_ action" => 'none',
|
||||
"message $_ own_action" => 'none')
|
||||
} @action_protos),
|
||||
});
|
||||
Irssi::expando_create('nickcumode', \&expando_nickcumode, {
|
||||
'message public' => 'none',
|
||||
'message own_public' => 'none',
|
||||
'message private' => 'none',
|
||||
'message own_private' => 'none',
|
||||
(map { ("message $_ action" => 'none',
|
||||
"message $_ own_action" => 'none')
|
||||
} @action_protos),
|
||||
});
|
||||
|
||||
sub init_hist {
|
||||
my ($server, $target) = @_;
|
||||
if (my $ch = $server->channel_find($target)) {
|
||||
[ max map { length } map { $_->{nick} } $ch->nicks ]
|
||||
}
|
||||
else {
|
||||
[ max map { length } $server->{nick}, $target ]
|
||||
}
|
||||
}
|
||||
|
||||
my %em = (
|
||||
p => '$nickalign',
|
||||
c => '$nickcolor',
|
||||
t => '$nicktrunc',
|
||||
m => '$nickcumode',
|
||||
);
|
||||
|
||||
my %formats = (
|
||||
own_action => [5, '{ownaction ', '$0','}','$1' ],
|
||||
action_public => [4, '{pubaction ', '$0','}','$1' ],
|
||||
action_private => [4, '{pvtaction ', '$0','}','$2' ],
|
||||
action_private_query => [4, '{pvtaction_query ','$0','}','$2' ],
|
||||
# * * * # * *
|
||||
|
||||
own_msg_private_query => [3, '{ownprivmsgnick ', '' ,'{ownprivnick ','$2','}','' ,'}','$1' ],
|
||||
msg_private_query => [2, '{privmsgnick ' ,'' ,'' ,'$0','' ,'' ,'}','$2' ],
|
||||
own_msg => [1, '{ownmsgnick ' ,'$2',' {ownnick ' ,'$0','}','' ,'}','$1' ],
|
||||
own_msg_channel => [1, '{ownmsgnick ' ,'$3',' {ownnick ' ,'$0','}','{msgchannel $1}','}','$2' ],
|
||||
pubmsg_me => [0, '{pubmsgmenick ' ,'$2',' {menick ' ,'$0','}','' ,'}','$1' ],
|
||||
pubmsg_me_channel => [0, '{pubmsgmenick ' ,'$3',' {menick ' ,'$0','}','{msgchannel $1}','}','$2' ],
|
||||
pubmsg_hilight => [0, '{pubmsghinick $0 ','$3',' ' ,'$1', '','', ,'}','$2' ],
|
||||
pubmsg_hilight_channel => [0, '{pubmsghinick $0 ','$4',' ' ,'$1', '','{msgchannel $2}','}','$3' ],
|
||||
pubmsg => [0, '{pubmsgnick ' ,'$2',' {pubnick ' ,'$0','}','' ,'}','$1' ],
|
||||
pubmsg_channel => [0, '{pubmsgnick ' ,'$3',' {pubnick ' ,'$0','}','{msgchannel $1}','}','$2' ],
|
||||
# * * * * * # * * * *
|
||||
);
|
||||
|
||||
sub reformat_format {
|
||||
Irssi::signal_remove('command format', 'update_formats');
|
||||
Irssi::signal_remove('theme changed' => 'update_formats');
|
||||
%format_ok = () unless @_;
|
||||
my ($mode, $server, $target, $nick, $size) = @_;
|
||||
for my $fmt (keys %formats) {
|
||||
next if defined $mode && $formats{$fmt}[0] != $mode;
|
||||
|
||||
my @fs = @{ $formats{$fmt} };
|
||||
|
||||
my $ls;
|
||||
if (defined $mode) {
|
||||
$ls = $size;
|
||||
}
|
||||
else {
|
||||
$ls = $fs[0] < 4 ? $S{max} : max(0, $S{max} - $S{melength});
|
||||
}
|
||||
next if exists $format_ok{$fmt} && $format_ok{$fmt} == $ls;
|
||||
|
||||
if ($S{truncate_nick} && $ls) {
|
||||
$fs[ $fs[0] < 4 ? 4 : 2 ] =~ s/\$/\$[.$ls]/;
|
||||
}
|
||||
if ($S{custom_modes} && $fs[0] < 4) {
|
||||
$fs[2] =~ s/\$\K\d/nickcumode/;
|
||||
}
|
||||
my $s;
|
||||
local $em{c} = ''
|
||||
if ($fs[1] =~ /menick/ && !$S{color_menick})
|
||||
|| ($fs[1] =~ /hinick/ && !$S{color_hinick});
|
||||
my $sr = $fs[0] >= 4 ? \@astyle : \@style;
|
||||
for my $i (1..$#fs) {
|
||||
$s .= ($sr->[$i] =~ s/(.)/$em{$1}/gr) if defined $sr->[$i];
|
||||
$s .= $fs[$i];
|
||||
}
|
||||
Irssi::command("^format $fmt $s");
|
||||
$format_ok{$fmt} = $ls;
|
||||
}
|
||||
Irssi::signal_add_last({
|
||||
'theme changed' => 'update_formats',
|
||||
'command format' => 'update_formats',
|
||||
});
|
||||
}
|
||||
|
||||
sub update_nm {
|
||||
my ($mode, $server, $target, $nick) = @_;
|
||||
my $tg = $server->{tag};
|
||||
if (my $ch = $server->channel_find($target)) {
|
||||
$target = $ch->{name};
|
||||
my $nickobj = $ch->nick_find($nick);
|
||||
if ($nickobj) {
|
||||
$nick = $nickobj->{nick};
|
||||
my $mode = substr $nickobj->{prefixes}.' ', 0, 1;
|
||||
$cumode_expando = exists $cmmap{$mode} ? format_expand($cmmap{$mode}) : $mode;
|
||||
}
|
||||
else {
|
||||
$cumode_expando = '';
|
||||
}
|
||||
}
|
||||
elsif (my $q = $server->query_find($target)) {
|
||||
$target = $q->{name};
|
||||
}
|
||||
|
||||
my $longest;
|
||||
if ($S{dynamic}) {
|
||||
my $hist = $histories{"$tg/$target"} ||= init_hist($server, $target);
|
||||
my $last = $histories{"$tg/$target/last"} || 1;
|
||||
unshift @$hist, length $nick;
|
||||
if (@$hist > 2*$S{history}) {
|
||||
splice @$hist, $S{history};
|
||||
}
|
||||
my @add;
|
||||
unless ($S{shrink}) {
|
||||
push @add, $last;
|
||||
}
|
||||
if ($S{staircase}) {
|
||||
push @add, $last - 1
|
||||
}
|
||||
$longest = $histories{"$tg/$target/last"} = max(@$hist, @add);
|
||||
|
||||
if ($S{max} && ($S{max} < $longest || !$S{shrink})) {
|
||||
$longest = $S{max};
|
||||
}
|
||||
}
|
||||
else {
|
||||
$longest = $S{max};
|
||||
}
|
||||
|
||||
my $size = $mode < 4 ? $longest : max(0, $longest - $S{melength});
|
||||
my $t_add = update_expando($mode, $server, $target, $nick, $size);
|
||||
$size = max(0, $size - $t_add) if defined $t_add;
|
||||
if ($S{dynamic}) {
|
||||
reformat_format($mode, $server, $target, $nick, $size);
|
||||
}
|
||||
}
|
||||
|
||||
sub sig_setup {
|
||||
my %old_S = %S;
|
||||
$S{history} = Irssi::settings_get_int('neat_history');
|
||||
$S{max} = Irssi::settings_get_int('neat_maxlength');
|
||||
$S{melength} = Irssi::settings_get_int('neat_melength');
|
||||
|
||||
$S{dynamic} = Irssi::settings_get_bool('neat_dynamic');
|
||||
$S{shrink} = Irssi::settings_get_bool('neat_shrink');
|
||||
$S{staircase} = Irssi::settings_get_bool('neat_staircase_shrink');
|
||||
|
||||
$S{color_hinick} = Irssi::settings_get_bool('neat_color_hinick');
|
||||
$S{color_menick} = Irssi::settings_get_bool('neat_color_menick');
|
||||
$S{truncate_nick} = Irssi::settings_get_bool('neat_truncate_nick');
|
||||
$S{custom_modes} = Irssi::settings_get_bool('neat_custom_modes');
|
||||
|
||||
if (!defined $old_S{dynamic} || $old_S{dynamic} != $S{dynamic}) {
|
||||
%histories = ();
|
||||
reformat_format();
|
||||
}
|
||||
elsif ($old_S{max} != $S{max} || $old_S{melength} != $S{melength}
|
||||
|| $old_S{color_hinick} != $S{color_hinick} || $old_S{color_menick} != $S{color_menick}
|
||||
|| $old_S{truncate_nick} != $S{truncate_nick} || $old_S{custom_modes} != $S{custom_modes}) {
|
||||
reformat_format();
|
||||
}
|
||||
}
|
||||
|
||||
sub update_formats {
|
||||
my $was_style = "@style";
|
||||
$S{style} = Irssi::current_theme->get_format(__PACKAGE__, 'neat_style');
|
||||
my $was_action_style = "@astyle";
|
||||
$S{action_style} = Irssi::current_theme->get_format(__PACKAGE__, 'neat_action_style');
|
||||
$S{pad_char} = Irssi::current_theme->get_format(__PACKAGE__, 'neat_pad_char');
|
||||
$S{tno_char} = Irssi::current_theme->get_format(__PACKAGE__, 'neat_notruncate_char');
|
||||
$S{tnolen} = length($S{tno_char} =~ s/$format_re//gr);
|
||||
$S{tyeslen} = length($S{tyes_char} =~ s/$format_re//gr);
|
||||
$S{tyes_char} = Irssi::current_theme->get_format(__PACKAGE__, 'neat_truncate_char');
|
||||
@style = map { y/pct//cd; $_ } split /,/, $S{style};
|
||||
@astyle = map { y/pctm//cd; $_ } split /,/, $S{action_style};
|
||||
$S{trunc_in_nick} = grep { /t/ } @style[2..min($#style, 6)];
|
||||
$S{trunc_in_anick} = grep { /t/ } @astyle[2..min($#astyle, 3)];
|
||||
my $custom_modes = Irssi::current_theme->get_format(__PACKAGE__, 'neat_custom_modes');
|
||||
%cmmap = map { (substr $_, 0, 1), (substr $_, 1) } $custom_modes =~ /(?:^\s?|\G\s?\|\s?)((?!\s\|)(?:[^\\|[:space:]]|\\.|\s(?!\||$))*)/sg;
|
||||
if ($was_style ne "@style" || $was_action_style ne "@astyle") {
|
||||
reformat_format();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my %format2control = (
|
||||
'F' => "\cDa", '_' => "\cDc", '|' => "\cDe", '#' => "\cDi", "n" => "\cDg", "N" => "\cDg",
|
||||
'U' => "\c_", '8' => "\cV", 'I' => "\cDf",
|
||||
);
|
||||
my %bg_base = (
|
||||
'0' => '0', '4' => '1', '2' => '2', '6' => '3', '1' => '4', '5' => '5', '3' => '6', '7' => '7',
|
||||
'x08' => '8', 'x09' => '9', 'x0a' => ':', 'x0b' => ';', 'x0c' => '<', 'x0d' => '=', 'x0e' => '>', 'x0f' => '?',
|
||||
);
|
||||
my %fg_base = (
|
||||
'k' => '0', 'b' => '1', 'g' => '2', 'c' => '3', 'r' => '4', 'm' => '5', 'p' => '5', 'y' => '6', 'w' => '7',
|
||||
'K' => '8', 'B' => '9', 'G' => ':', 'C' => ';', 'R' => '<', 'M' => '=', 'P' => '=', 'Y' => '>', 'W' => '?',
|
||||
);
|
||||
my @ext_colour_off = (
|
||||
'.', '-', ',',
|
||||
'+', "'", '&',
|
||||
);
|
||||
sub format_expand {
|
||||
$_[0] =~ s{%(Z.{6}|z.{6}|X..|x..|.)}{
|
||||
my $c = $1;
|
||||
if (exists $format2control{$c}) {
|
||||
$format2control{$c}
|
||||
}
|
||||
elsif (exists $bg_base{$c}) {
|
||||
"\cD/$bg_base{$c}"
|
||||
}
|
||||
elsif (exists $fg_base{$c}) {
|
||||
"\cD$fg_base{$c}/"
|
||||
}
|
||||
elsif ($c =~ /^[{}%]$/) {
|
||||
$c
|
||||
}
|
||||
elsif ($c =~ /^(z|Z)([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})$/) {
|
||||
my $bg = $1 eq 'z';
|
||||
my (@rgb) = map { hex $_ } $2, $3, $4;
|
||||
my $x = $bg ? 0x1 : 0;
|
||||
my $out = "\cD" . (chr -13 + ord '0');
|
||||
for (my $i = 0; $i < 3; ++$i) {
|
||||
if ($rgb[$i] > 0x20) {
|
||||
$out .= chr $rgb[$i];
|
||||
}
|
||||
else {
|
||||
$x |= 0x10 << $i; $out .= chr 0x20 + $rgb[$i];
|
||||
}
|
||||
}
|
||||
$out .= chr 0x20 + $x;
|
||||
$out
|
||||
}
|
||||
elsif ($c =~ /^(x)(?:0([[:xdigit:]])|([1-6])(?:([0-9])|([a-z]))|7([a-x]))$/i) {
|
||||
my $bg = $1 eq 'x';
|
||||
my $col = defined $2 ? hex $2
|
||||
: defined $6 ? 232 + (ord lc $6) - (ord 'a')
|
||||
: 16 + 36 * ($3 - 1) + (defined $4 ? $4 : 10 + (ord lc $5) - (ord 'a'));
|
||||
if ($col < 0x10) {
|
||||
my $chr = chr $col + ord '0';
|
||||
"\cD" . ($bg ? "/$chr" : "$chr/")
|
||||
}
|
||||
else {
|
||||
"\cD" . $ext_colour_off[($col - 0x10) / 0x50 + $bg * 3] . chr (($col - 0x10) % 0x50 - 1 + ord '0')
|
||||
}
|
||||
}
|
||||
else {
|
||||
"%$c"
|
||||
}
|
||||
}ger;
|
||||
}
|
||||
}
|
||||
|
||||
sub init {
|
||||
update_formats();
|
||||
sig_setup();
|
||||
lock_keys(%S);
|
||||
print "nm2 experimental version, please report issues. thanks!"
|
||||
}
|
||||
|
||||
Irssi::settings_add_bool('misc', 'neat_dynamic', 1);
|
||||
Irssi::settings_add_bool('misc', 'neat_shrink', 1);
|
||||
Irssi::settings_add_bool('misc', 'neat_staircase_shrink', 0);
|
||||
|
||||
Irssi::settings_add_bool('misc', 'neat_color_hinick', 0);
|
||||
Irssi::settings_add_bool('misc', 'neat_color_menick', 0);
|
||||
Irssi::settings_add_bool('misc', 'neat_truncate_nick', 1);
|
||||
Irssi::settings_add_bool('misc', 'neat_custom_modes', 0);
|
||||
|
||||
Irssi::settings_add_int('misc', 'neat_maxlength', 0);
|
||||
Irssi::settings_add_int('misc', 'neat_melength', 2);
|
||||
Irssi::settings_add_int('misc', 'neat_history', 50);
|
||||
|
||||
Irssi::signal_add('setup changed' => 'sig_setup');
|
||||
Irssi::signal_add_last({
|
||||
'setup reread' => 'sig_setup',
|
||||
'theme changed' => 'update_formats',
|
||||
'command format' => 'update_formats',
|
||||
});
|
||||
|
||||
Irssi::theme_register([
|
||||
'neat_style' => ' , , p , , c , t , , , ',
|
||||
'neat_action_style' => ' , p , , t , ',
|
||||
'neat_pad_char' => '%K.',
|
||||
'neat_truncate_char' => '%m+',
|
||||
'neat_notruncate_char' => '',
|
||||
'neat_custom_modes' => '&%B&%n | @%g@%n | +%y+%n',
|
||||
]);
|
||||
|
||||
Irssi::signal_add_first({
|
||||
'message public' => sub {
|
||||
my ($server, $msg, $nick, $address, $target) = @_;
|
||||
update_nm(0, $server, $target, $nick);
|
||||
},
|
||||
'message private' => sub {
|
||||
my ($server, $msg, $nick, $address) = @_;
|
||||
update_nm(2, $server, $nick, $nick);
|
||||
},
|
||||
(map { ("message $_ action" => sub {
|
||||
my ($server, $msg, $nick, $address, $target) = @_;
|
||||
update_nm(4, $server, $target, $nick);
|
||||
}) } qw(irc silc)),
|
||||
'message xmpp action' => sub {
|
||||
return unless @_;
|
||||
my ($server, $msg, $nick, $target) = @_;
|
||||
update_nm(4, $server, $target, $nick);
|
||||
},
|
||||
});
|
||||
|
||||
sub channel_nick {
|
||||
my ($server, $target) = @_;
|
||||
($server->channel_find($target)||+{ownnick=>$server})->{ownnick}{nick}
|
||||
}
|
||||
|
||||
Irssi::signal_add_first({
|
||||
'message own_public' => sub {
|
||||
my ($server, $msg, $target) = @_;
|
||||
update_nm(1, $server, $target, channel_nick($server, $target));
|
||||
},
|
||||
'message own_private' => sub {
|
||||
my ($server, $msg, $target) = @_;
|
||||
update_nm(3, $server, $target, $server->{nick});
|
||||
},
|
||||
(map { ("message $_ own_action" => sub {
|
||||
my ($server, $msg, $target) = @_;
|
||||
update_nm(5, $server, $target, $server->{nick});
|
||||
}) } qw(irc silc)),
|
||||
'message xmpp own_action' => sub {
|
||||
return unless @_;
|
||||
my ($server, $msg, $target) = @_;
|
||||
update_nm(5, $server, $target, channel_nick($server, $target));
|
||||
},
|
||||
});
|
||||
Irssi::signal_add_last({
|
||||
'channel destroyed' => sub {
|
||||
my ($channel) = @_;
|
||||
delete $histories{ $channel->{server}{tag} . '/' . $channel->{name} };
|
||||
delete $histories{ $channel->{server}{tag} . '/' . $channel->{name} . '/last' };
|
||||
},
|
||||
'query destroyed' => sub {
|
||||
my ($query) = @_;
|
||||
delete $histories{ $query->{server}{tag} . '/' . $query->{name} };
|
||||
delete $histories{ $query->{server}{tag} . '/' . $query->{name} . '/last' };
|
||||
},
|
||||
'query nick changed' => sub {
|
||||
my ($query, $old_nick) = @_;
|
||||
delete $histories{ $query->{server}{tag} . '/' . $old_nick };
|
||||
delete $histories{ $query->{server}{tag} . '/' . $old_nick . '/last' };
|
||||
},
|
||||
'query server changed' => sub {
|
||||
my ($query, $old_server) = @_;
|
||||
delete $histories{ $old_server->{tag} . '/' . $query->{name} };
|
||||
delete $histories{ $old_server->{tag} . '/' . $query->{name} . '/last' };
|
||||
}
|
||||
});
|
||||
Irssi::signal_add({
|
||||
'print text' => 'prnt_clear_levels',
|
||||
});
|
||||
|
||||
init();
|
||||
|
||||
# Changelog
|
||||
# =========
|
||||
# 2.1 - support realnames script
|
||||
#
|
||||
# 2.0
|
||||
# - fix crash if xmpp action signal is not registered (just ignore it)
|
||||
# - do not grow either when using no-shrink with maxlength
|
||||
# - hopefully fix alignment in xmpp muc
|
||||
169
plan3.md
Normal file
169
plan3.md
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
# KOMPLEKSOWY PLAN IMPLEMENTACJI - NOWE PODEJŚCIE
|
||||
|
||||
## WYTYCZNE OBOWIĄZKOWE:
|
||||
1. **Zawsze pamiętaj kontekst**: `msg_flow.md` i `summary.md`
|
||||
2. **Nie zbaczaj z wyznaczonej ścieżki** - trzymaj się planu
|
||||
3. **Checkpoint commits**: Po zmianach commit z pushem zawierający info o zmianach i timestamp (data + dokładna godzina)
|
||||
4. **ZAKAZ `ninja Build install`** - tylko build do sprawdzenia błędów kompilacji
|
||||
|
||||
## ANALIZA PROBLEMU
|
||||
|
||||
**KLUCZOWA OBSERWACJA**: Po analizie `msg_flow.md` i `summary.md` widzę, że:
|
||||
|
||||
1. ❌ **`parse_special` + `ALIGN_COMBINE_MODE`** - już próbowane, problem z kolorami
|
||||
2. ❌ **Expandos** - nie mają dostępu do `arglist`, zwracają puste stringi
|
||||
3. ✅ **NOWE ROZWIĄZANIE**: Modyfikacja na poziomie **`format_get_text_args`** (krok 10 w flow)
|
||||
|
||||
## STRATEGIA: INTEGRACJA Z ARGUMENTAMI FORMATOWANIA
|
||||
|
||||
### KLUCZOWA IDEA:
|
||||
Zamiast modyfikować `parse_special` lub tworzyć expandos, **wstrzykniemy dodatkowy parametr padding bezpośrednio do `arglist`** w `format_get_text_args()`.
|
||||
|
||||
## PLAN IMPLEMENTACJI
|
||||
|
||||
### FAZA 1: Przygotowanie Infrastruktury
|
||||
|
||||
#### 1.1 Dodanie ustawień konfiguracyjnych
|
||||
**Plik**: `src/fe-common/core/fe-settings.c`
|
||||
```c
|
||||
// Dodać do settings_add_*():
|
||||
settings_add_bool("lookandfeel", "nick_column_enabled", FALSE);
|
||||
settings_add_int("lookandfeel", "nick_column_width", 12);
|
||||
```
|
||||
|
||||
#### 1.2 Dodanie flag do TEXT_DEST_REC
|
||||
**Plik**: `src/fe-common/core/printtext.h`
|
||||
```c
|
||||
typedef struct {
|
||||
// ... istniejące pola
|
||||
int flags; // nowe pole dla flag formatowania
|
||||
} TEXT_DEST_REC;
|
||||
|
||||
#define PRINT_FLAG_NICK_COLUMN 0x01
|
||||
```
|
||||
|
||||
### FAZA 2: Modyfikacja Flow Formatowania
|
||||
|
||||
#### 2.1 Ustawienie flagi w obsłudze wiadomości
|
||||
**Plik**: `src/fe-common/core/fe-messages.c`
|
||||
|
||||
W funkcjach `sig_message_public()` i `sig_message_own_public()`:
|
||||
```c
|
||||
// Po utworzeniu dest przez format_create_dest()
|
||||
if (settings_get_bool("nick_column_enabled")) {
|
||||
dest.flags |= PRINT_FLAG_NICK_COLUMN;
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2 Główna logika w format_get_text_args
|
||||
**Plik**: `src/fe-common/core/formats.c`
|
||||
|
||||
W funkcji `format_get_text_args()` (krok 10 flow), **PRZED** pętlą parsowania:
|
||||
|
||||
```c
|
||||
// Sprawdź czy nick column jest włączony
|
||||
if (dest && (dest->flags & PRINT_FLAG_NICK_COLUMN)) {
|
||||
// Znajdź parametry mode i nick w arglist
|
||||
char *mode = NULL, *nick = NULL;
|
||||
|
||||
// Dla TXT_PUBMSG: args[0]=nick, args[3]=nickmode
|
||||
// Dla TXT_OWN_MSG: args[0]=nick, args[3]=nickmode
|
||||
if (args && args[0] && args[3]) {
|
||||
nick = args[0];
|
||||
mode = args[3];
|
||||
|
||||
// Oblicz padding
|
||||
int width = settings_get_int("nick_column_width");
|
||||
int mode_len = strlen(mode);
|
||||
int nick_len = strlen(nick);
|
||||
int total_len = mode_len + nick_len;
|
||||
|
||||
if (total_len < width) {
|
||||
int padding_len = width - total_len;
|
||||
char *padding = g_strnfill(padding_len, ' ');
|
||||
|
||||
// Wstrzyknij padding jako nowy parametr na początku
|
||||
// Przesuń wszystkie argumenty o 1 pozycję w prawo
|
||||
// args[0] = padding, args[1] = nick, args[4] = mode
|
||||
// Theme będzie używać: $0 (padding) + $4 (mode) + $1 (nick)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### FAZA 3: Modyfikacja Theme
|
||||
|
||||
#### 3.1 Aktualizacja abstracts w default.theme
|
||||
```theme
|
||||
# Gdy nick_column_enabled = ON, argumenty są przesunięte:
|
||||
# $0 = padding (nowy)
|
||||
# $1 = nick (przesunięty z $0)
|
||||
# $4 = mode (przesunięty z $3)
|
||||
|
||||
# Podstawowy abstract z padding
|
||||
msgnick = "%K<%n$0%B$4%N%g$1%K>%n %|";
|
||||
|
||||
# Own messages
|
||||
ownmsgnick = "{msgnick $0 $4 $1}";
|
||||
|
||||
# Public messages
|
||||
pubmsgnick = "{msgnick $0 $4 $1}";
|
||||
```
|
||||
|
||||
### FAZA 4: Testowanie i Debugowanie
|
||||
|
||||
#### 4.1 Dodanie debug outputu
|
||||
```c
|
||||
// W format_get_text_args() dodać:
|
||||
if (settings_get_bool("debug_nick_column")) {
|
||||
printf("DEBUG: nick_column - padding='%s', mode='%s', nick='%s'\n",
|
||||
padding, mode, nick);
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.2 Checkpoint commit
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "[nick_column] FAZA 1-4: Infrastruktura + logika padding - 2025-01-24 15:30"
|
||||
git push origin irssip
|
||||
```
|
||||
|
||||
## HARMONOGRAM IMPLEMENTACJI
|
||||
|
||||
### Dzień 1: Infrastruktura
|
||||
- [ ] Dodanie ustawień (`nick_column_enabled`, `nick_column_width`)
|
||||
- [ ] Dodanie flag do `TEXT_DEST_REC`
|
||||
- [ ] Checkpoint commit
|
||||
|
||||
### Dzień 2: Logika formatowania
|
||||
- [ ] Modyfikacja `sig_message_public()` i `sig_message_own_public()`
|
||||
- [ ] Implementacja logiki padding w `format_get_text_args()`
|
||||
- [ ] Checkpoint commit
|
||||
|
||||
### Dzień 3: Theme i testowanie
|
||||
- [ ] Aktualizacja `default.theme`
|
||||
- [ ] Dodanie debug outputu
|
||||
- [ ] Build test (bez install)
|
||||
- [ ] Checkpoint commit
|
||||
|
||||
## PRZEWIDYWANE WYZWANIA
|
||||
|
||||
### 1. Przesunięcie argumentów
|
||||
**Problem**: Wstrzyknięcie padding przesuwa wszystkie argumenty
|
||||
**Rozwiązanie**: Dokładne mapowanie argumentów w theme
|
||||
|
||||
### 2. Kompatybilność wsteczna
|
||||
**Problem**: Theme musi działać z wyłączonym nick_column
|
||||
**Rozwiązanie**: Warunki w theme lub osobne abstracts
|
||||
|
||||
### 3. Różne formaty wiadomości
|
||||
**Problem**: `TXT_PUBMSG`, `TXT_OWN_MSG`, `TXT_PUBMSG_HILIGHT` mają różne argumenty
|
||||
**Rozwiązanie**: Mapowanie per format type
|
||||
|
||||
## KRYTERIA SUKCESU
|
||||
|
||||
✅ **Wyrównanie działa** - nicki wyrównane do prawej w kolumnie
|
||||
✅ **Kolory zachowane** - osobne kolory dla mode i nick
|
||||
✅ **Konfigurowalność** - szerokość przez ustawienia
|
||||
✅ **Kompatybilność** - działa z wyłączonym nick_column
|
||||
✅ **Brak wpływu na resztę** - standardowe formatowanie nietknięte
|
||||
45
summary.md
45
summary.md
|
|
@ -162,25 +162,32 @@ Fundamentalny konflikt:
|
|||
2. **Wymóg kolorów**: Tryb i nick potrzebują osobnego formatowania kolorów z abstrakcji motywu
|
||||
3. **Obecne ograniczenie**: Po połączeniu w C, motyw widzi pojedynczy string i nie może zastosować osobnych kolorów
|
||||
|
||||
## HISTORIA PRÓB IMPLEMENTACJI
|
||||
|
||||
### PRÓBA 1: Parse Special + ALIGN_COMBINE_MODE (2025-01-24)
|
||||
**Podejście**: Modyfikacja `parse_special()` z flagą `&` do łączenia mode+nick przed wyrównaniem.
|
||||
**Problem**: Ograniczenie interpretacji kolorów - po połączeniu mode+nick w jeden string, theme nie może zastosować osobnych kolorów.
|
||||
**Status**: ❌ Niepowodzenie
|
||||
|
||||
### PRÓBA 2: Expandos bez kontekstu (wcześniej)
|
||||
**Podejście**: Tworzenie expandos `nick_with_mode`, `nick_padding` itp.
|
||||
**Problem**: Expandos nie mają dostępu do `arglist` z formatowania - zwracają puste stringi.
|
||||
**Status**: ❌ Niepowodzenie
|
||||
|
||||
### PRÓBA 3: Modyfikacja format_get_text_args (2025-01-24)
|
||||
**Podejście**: Wstrzyknięcie dodatkowego parametru padding do `arglist` w `format_get_text_args()`.
|
||||
**Problem**: Błędna analiza argumentów - myślałem że `$0=nick`, ale `$0=mode`, `$1=nick`. Przesuwanie argumentów psuło mapowanie.
|
||||
**Status**: ❌ Niepowodzenie - fundamentalnie błędne założenia
|
||||
|
||||
### WNIOSKI Z NIEPOWODZEŃ:
|
||||
1. **Modyfikacja argumentów formatowania jest ryzykowna** - łatwo zepsuć istniejące mapowanie
|
||||
2. **Expandos bez kontekstu nie działają** - potrzebują dostępu do aktualnych danych message
|
||||
3. **Analiza flow musi być dokładna** - błędne założenia prowadzą do niefunkcjonalnych rozwiązań
|
||||
|
||||
## AKTUALNE USTALENIA (2025-01-24)
|
||||
|
||||
### Analiza Flow Wiadomości
|
||||
Przeprowadzono szczegółową analizę flow wiadomości w Irssi od otrzymania z serwera do wyświetlenia (dokumentacja w `msg_flow.md`). Zidentyfikowano fundamentalny problem z podejściem expandos.
|
||||
### Rekomendowane Rozwiązanie: Expandos z kontekstem sygnałów
|
||||
**INSPIRACJA**: Skrypt nm2.pl pokazuje właściwe podejście - expandos + sygnały + dynamiczne przepisywanie formatów.
|
||||
|
||||
### Problem z Expandos
|
||||
Expandos nie mają dostępu do `arglist` z formatowania - są wywoływane globalnie bez kontekstu lokalnego formatowania. To powoduje, że zwracają puste stringi zamiast rzeczywistych wartości mode i nick.
|
||||
|
||||
### Rekomendowane Rozwiązanie
|
||||
**Rozszerzenie systemu wyrównania w `parse_special`** zamiast expandos:
|
||||
|
||||
1. **Nowa składnia**: `$[~&nick_column]0` - wyrównanie z flagą nick_column
|
||||
2. **Zachowuje osobne parametry** - mode ($0) i nick ($1) pozostają oddzielne dla kolorowania
|
||||
3. **Zgodne z roadmapą Irssi** - "variable/dynamic expandos with arguments"
|
||||
4. **Eleganckie kodowo** - rozszerza istniejący system zamiast go obchodzić
|
||||
|
||||
### Wymagania Implementacji
|
||||
- Rozszerzyć `get_alignment_args()` o flagę `&nick_column`
|
||||
- Dodać `ALIGN_NICK_COLUMN` do special-vars.h
|
||||
- Implementować logikę kombinowania mode+nick przed wyrównaniem
|
||||
- Zachować osobne parametry po wyrównaniu dla theme
|
||||
- Ustawienia: `nick_column_enabled` i `nick_column_width`
|
||||
**KLUCZOWA IDEA**:
|
||||
Zamiast modyfikować argumenty, stworzyć expando który zwraca gotowy string z paddingiem, mode i nickiem.
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@ abstracts = {
|
|||
# ban/ban exception/invite list mask is printed
|
||||
ban = "%c$*%n";
|
||||
|
||||
|
||||
##
|
||||
## messages
|
||||
##
|
||||
|
|
@ -167,9 +166,6 @@ abstracts = {
|
|||
# private message in query
|
||||
privmsgnick = "{msgnick %R$*%n}";
|
||||
|
||||
# channel name is printed with message
|
||||
msgchannel = "%K:%c$*%n";
|
||||
|
||||
##
|
||||
## Actions (/ME stuff)
|
||||
##
|
||||
|
|
@ -193,7 +189,6 @@ abstracts = {
|
|||
# public action sent by others
|
||||
pubaction = "{action $*}";
|
||||
|
||||
|
||||
##
|
||||
## other IRC events
|
||||
##
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue