Changeset 130633c


Ignore:
Timestamp:
Jul 17, 2009, 9:46:45 PM (15 years ago)
Author:
Nelson Elhage <nelhage@mit.edu>
Branches:
master, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
2f2a643, f9c93cd
Parents:
a52d13a (diff), c08a725 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:
Merge branch 'automake'

Conflicts:
	Makefile.in
	libfaim/Makefile.in
	owl.h
Files:
4 added
6 deleted
27 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    rd5ef539 r37f27bc  
    44*~
    55.#*
     6.deps
    67META.yml
    78Makefile
     9/Makefile.in
     10/libfaim/Makefile.in
    811Makefile.old
    912TAGS
     
    2023configure
    2124core
     25depcomp
     26install-sh
    2227jabber.log
     28missing
    2329owl_prototypes.h
    2430owl_prototypes.h.new
     
    2632perlwrap.c
    2733pm_to_blib
     34stamp-h1
    2835tester
    2936varstubs.c
  • autogen.sh

    r130479b r37f27bc  
    11#!/bin/sh
    2 autoreconf
     2autoreconf -fvi
     3
  • configure.ac

    r4097723 r130633c  
    11dnl $Id$
    22dnl Process this file with autoconf to produce a configure script.
    3 AC_INIT(owl.c)
     3AC_INIT([BarnOwl],[1.3],[bug-barnowl@mit.edu])
     4AM_INIT_AUTOMAKE([-Wall foreign])
    45
    5 AC_CONFIG_HEADER(config.h)
     6AC_CONFIG_HEADER([config.h])
    67
    78AC_PROG_CC
    8 
    9 dnl If we're using GCC, enable all warnings
    10 if test "$GCC" = yes; then
    11      CFLAGS="$CFLAGS -Wall -g";
    12 fi
    139
    1410dnl Check for Athena
     
    9793   ])])
    9894
    99 AC_ARG_ENABLE([athstatic], AS_HELP_STRING([--enable-athstatic],
    100                                           [Statically link libraries in /usr/athena/lib]),
    101                                           [ATHSTATIC=./athstatic],
    102                                           [ATHSTATIC=])
    103 
    10495AC_CHECK_FUNCS(use_default_colors resizeterm des_string_to_key des_key_sched des_ecb_encrypt)
    10596AC_CHECK_FUNCS(                            DES_string_to_key  DES_ecb_encrypt DES_key_sched)
     
    143134dnl Add LDFLAGS for embedded perl
    144135FOO=`perl -MExtUtils::Embed -e ldopts`
    145 AC_MSG_NOTICE([Adding perl LDFLAGS ${FOO}])
    146 LDFLAGS=${LDFLAGS}\ ${FOO}
     136AC_MSG_NOTICE([Adding perl LIBS ${FOO}])
     137LIBS=${LIBS}\ ${FOO}
    147138
    148139dnl Add CFLAGS and LDFLAGS for glib-2.0
     
    154145LDFLAGS="${GLIB_LIBS} ${LDFLAGS}"
    155146
     147if test "x${prefix}" = "xNONE"; then
     148   prefix="${ac_default_prefix}"
     149fi
     150
     151AC_DEFINE_UNQUOTED([DATADIR],["${prefix}/share/${PACKAGE}"],
     152                   [Package data directory])
     153
    156154dnl Checks for typedefs, structures, and compiler characteristics.
    157 
    158 dnl Support --program-{prefix,suffix,transform}
    159 AC_ARG_PROGRAM
    160155
    161156AC_SUBST(XSUBPPDIR)
    162157AC_SUBST(XSUBPPFLAGS)
    163 AC_SUBST(ATHSTATIC)
    164158
    165159AC_PROG_INSTALL
     160AC_PROG_RANLIB
    166161
    167 AC_CONFIG_SUBDIRS(libfaim)
    168 
    169 AC_OUTPUT(Makefile)
     162AC_CONFIG_FILES([Makefile libfaim/Makefile])
     163AC_OUTPUT([perl/modules/Makefile])
  • owl.h

    ra88f35a r130633c  
    4848static const char owl_h_fileIdent[] = "$Id$";
    4949
    50 #define BARNOWL_STRINGIFY(x) _STRINGIFY(x)
    51 #define _STRINGIFY(x) #x
    52 
    53 #ifndef OWL_VERSION_STRING
    54 #define OWL_VERSION_STRING "1.3"
    55 #endif
     50#define OWL_VERSION_STRING PACKAGE_VERSION
    5651
    5752/* Feature that is being tested to redirect stderr through a pipe.
  • scripts/do-release

    r11b9017 rdb98968  
    66}
    77
    8 VERS=$(perl -lne 'print $1 if m{^#define\s+OWL_VERSION_STRING\s+"([^"]+)"\s*$}' owl.h) \
     8VERS=$(perl -ne 'print $1 if m{^AC_INIT\(\[[^\]]+\],\s*\[([^\]]+)\]}' configure.ac) \
    99    || die "Unable to parse barnowl version"
    1010TAG=barnowl-$VERS
     
    2929CODIR=$(pwd)
    3030cd "$TMPDIR/$TGZ"
    31 autoreconf
     31autoreconf -fvi
    3232cd "$TMPDIR"
    3333tar czvf "$TGZ.tgz" "$TGZ"
  • scripts/locker-build

    re477a53 r130633c  
    7575(
    7676    cd "$TMPDIR"/* || die "Unable to cd to $TMPDIR"
    77     VERS=$(perl -ne 'print $1 if m{^#define\s*OWL_VERSION_STRING\s*"([^"]+)"}' owl.h)
     77    VERS=$(perl -ne 'print $1 if m{^AC_INIT\(\[[^\]]+\],\s*\[([^\]]+)\]}' configure.ac)
    7878    test -z "$VERS" && die "Unable to detect barnowl version."
    7979
  • ChangeLog

    r68f1afe r5df4b9a  
     11.2.1
     2 * Fix building with Zephyr support. -nelhage
     3 * Support --with-stack-protector in 'configure'. -nelhage
     4
     51.2
     6 * Fix some typos in source and messages. -adehnert
     7 * Support an explicit --with{out,}-zephyr configure option. -nelhage
     8 * Display a nicer error in :blist if .anyone doesn't exist. -geofft
     9 * Don't zcrypt shift-R replies to zcrypted messages -adehnert
     10 * Export a time_t for messages to perl as 'unix_time' -nelhage
     11 * Get rid of cryptic numeric messages after IRC commands. -ezyang
     12 * IRC: Include IRC admin messages in the 'irc' filter. -geofft
     13 * Fix M-LEFT and M-RIGHT bindings. -nelhage
     14 * Fix replycmd to use right class/instance -adehnert
     15 * Allow SIGINT to interrupt getting the Zephyr buddy list -nelhage
     16 * Break perlwrap.pm into multiple files. -nelhage
     17 * Handle errors in perlwrap.pm better. -nelhage
     18 * Don't attempt to send a Zephyr logout if we never initialized Zephyr. -nelhage
     19 * Display personals better in OneLine mode. -adehnert
     20 * Display context for pings -adehnert
     21 * Support --program-{prefix,suffix,transform}. -nelhage
     22 * Send instanced pings and give useful error messages -adehnert
     23 * Add <message,*,%me%> to default Barnowl subs. -adehnert
     24 * Maintain instance when using shift-R on personals -adehnert
     25 * Improve handling of outgoing instanced personals -adehnert
     26 * Don't require personals to be -i personal. -geofft
     27 * Display context for personals, so as to make <message,*,%me> usable. -geofft
     28 * Implement mark and swap in the message list. -asedeno
     29 * Fix handling of C-SPACE. -nelhage
     30 * Fix some warnings. -nelhage
     31 * Handle SIGINT, and make ^C interrupt searches. -nelhage
     32 * Fix the usage line for punt/unpunt -nelhage
     33 * Small bugfixes to release scripts. -nelhage
     34
    1351.1.1
    236 * Fix bogus errors 'subscribing to login messages'. -nelhage
  • codelist.pl

    r09489b89 r0982901  
    88
    99foreach $file (@ARGV) {
     10    next if $file eq 'perlglue.c';
    1011    open(FILE, $file);
    1112
  • commands.c

    r73ba824 r2fc8397  
    881881                  "", ""),
    882882
     883  OWLCMD_VOID_CTX("edit:set-mark", owl_editwin_set_mark,
     884                  OWL_CTX_EDIT,
     885                  "sets the mark",
     886                  "", ""),
     887
     888  OWLCMD_VOID_CTX("edit:exchange-point-and-mark", owl_editwin_exchange_point_and_mark,
     889                  OWL_CTX_EDIT,
     890                  "exchanges the point and the mark",
     891                  "", ""),
     892
     893  OWLCMD_VOID_CTX("edit:copy-region-as-kill", owl_editwin_copy_region_as_kill,
     894                  OWL_CTX_EDIT,
     895                  "copy the text between the point and the mark",
     896                  "", ""),
     897
     898  OWLCMD_VOID_CTX("edit:kill-region", owl_editwin_kill_region,
     899                  OWL_CTX_EDIT,
     900                  "kill text between the point and the mark",
     901                  "", ""),
     902
     903  OWLCMD_VOID_CTX("edit:yank", owl_editwin_yank,
     904                  OWL_CTX_EDIT,
     905                  "insert the current text from the kill buffer",
     906                  "", ""),
     907
    883908  OWLCMD_VOID_CTX("editline:done", owl_command_editline_done,
    884909                  OWL_CTX_EDITLINE,
     
    913938                  "runs 'editmulti:done'.\n"\
    914939                  "Otherwise runs 'edit:delete-next-char'\n"),
     940
     941  OWLCMD_VOID_CTX("editmulti:forward-paragraph", owl_editwin_forward_paragraph,
     942                  OWL_CTX_EDITMULTI,
     943                  "Move forward to end of paragraph.",
     944                  "",
     945                  "Move the point to the end of the current paragraph"),
     946
     947  OWLCMD_VOID_CTX("editmulti:backward-paragraph", owl_editwin_backward_paragraph,
     948                  OWL_CTX_EDITMULTI,
     949                  "Move backward to the start of paragraph.",
     950                  "",
     951                  "Move the point to the start of the current paragraph"),
    915952
    916953  /****************************************************************/
     
    26582695  owl_function_makemsg("Command cancelled.");
    26592696
    2660   if(e->echochar == 0) {
     2697  if(owl_editwin_get_echochar(e) == 0) {
    26612698    hist=owl_editwin_get_history(e);
    26622699    owl_history_store(hist, owl_editwin_get_text(e));
  • editwin.c

    r50e671c r72ab15f  
    77static const char fileIdent[] = "$Id$";
    88
    9 #define INCR 5000
     9#define VALID_EXCURSION (0x9a2b4729)
     10
     11typedef struct _owl_editwin_excursion { /*noproto*/
     12  int valid;
     13  int index;
     14  int mark;
     15  int goal_column;
     16  int lock;
     17  struct _owl_editwin_excursion *next;
     18} oe_excursion;
     19
     20struct _owl_editwin { /*noproto*/
     21  char *buff;
     22  owl_history *hist;
     23  int bufflen;
     24  int allocated;
     25  int index;
     26  int mark;
     27  char *killbuf;
     28  int goal_column;
     29  int topindex;
     30  int cursorx;
     31  int winlines, wincols, fillcol, wrapcol;
     32  WINDOW *curswin;
     33  int style;
     34  int lock;
     35  int dotsend;
     36  int echochar;
     37  oe_excursion *excursions;
     38
     39  char *command;
     40  void (*callback)(struct _owl_editwin*);
     41  void *cbdata;
     42};
     43
     44static void oe_reframe(owl_editwin *e);
     45static void oe_save_excursion(owl_editwin *e, oe_excursion *x);
     46static void oe_release_excursion(owl_editwin *e, oe_excursion *x);
     47static void oe_restore_excursion(owl_editwin *e, oe_excursion *x);
     48static void oe_restore_mark_only(owl_editwin *e, oe_excursion *x);
     49static int oe_count_glyphs(char *s);
     50static int oe_char_width(gunichar c, int column);
     51static int oe_region_width(owl_editwin *e, int start, int end, int width);
     52static int oe_find_display_line(owl_editwin *e, int *x, int index);
     53static void oe_insert_char(owl_editwin *e, gunichar c);
     54static int owl_editwin_limit_maxcols(int v, int maxv);
     55static int owl_editwin_check_dotsend(owl_editwin *e);
     56static int owl_editwin_is_char_in(owl_editwin *e, char *set);
     57static gunichar owl_editwin_get_char_at_point(owl_editwin *e);
     58static int owl_editwin_replace_internal(owl_editwin *e, int replace, char *s);
     59static char *oe_copy_buf(owl_editwin *e, char *buf, int len);
     60static int oe_copy_region(owl_editwin *e);
     61static char *oe_chunk(owl_editwin *e, int start, int end);
     62
     63#define INCR 4096
     64
     65#define WHITESPACE " \n\t"
     66
     67owl_editwin *owl_editwin_allocate(void)
     68{
     69  owl_editwin *e;
     70  e = owl_malloc(sizeof(owl_editwin));
     71  memset(e, 0, sizeof(*e));
     72  return e;
     73}
     74
     75static int oe_count_glyphs(char *s)
     76{
     77  int count = 0;
     78  char *p;
     79
     80  for(p = s; *p != 0; p = g_utf8_find_next_char(p, NULL))
     81    if (!g_unichar_ismark(g_utf8_get_char(p)))
     82      count++;
     83
     84  return count;
     85}
     86
     87static inline void oe_set_index(owl_editwin *e, int index)
     88{
     89  if (index != e->index) {
     90    e->goal_column = -1;
     91    e->cursorx = -1;
     92  }
     93  e->index = index;
     94}
     95
     96static inline void oe_set_mark(owl_editwin *e, int mark)
     97{
     98  e->mark = mark;
     99}
     100
     101void owl_editwin_set_mark(owl_editwin *e)
     102{
     103  oe_set_mark(e, e->index);
     104  /* owl_function_makemsg("Mark set."); */
     105}
    10106
    11107/* initialize the editwin e.
     
    14110void owl_editwin_init(owl_editwin *e, WINDOW *win, int winlines, int wincols, int style, owl_history *hist)
    15111{
    16   e->buff=owl_malloc(INCR); 
     112  e->buff=owl_malloc(INCR);
    17113  e->buff[0]='\0';
    18114  e->bufflen=0;
    19115  e->hist=hist;
    20116  e->allocated=INCR;
    21   e->buffx=0;
    22   e->buffy=0;
    23   e->topline=0;
    24   e->winlines=winlines;
    25   e->wincols=wincols;
    26   e->fillcol=owl_editwin_limit_maxcols(wincols-7, owl_global_get_edit_maxfillcols(&g));
    27   e->wrapcol=owl_editwin_limit_maxcols(wincols-7, owl_global_get_edit_maxwrapcols(&g));
    28   e->curswin=win;
     117  oe_set_index(e, 0);
     118  oe_set_mark(e, -1);
     119  if (e->killbuf != NULL)
     120    free(e->killbuf);
     121  e->killbuf = NULL;
     122  e->goal_column = -1;
     123  e->cursorx = -1;
     124  e->topindex = 0;
     125  e->excursions = NULL;
     126  owl_editwin_set_curswin(e, win, winlines, wincols);
    29127  e->style=style;
    30128  if ((style!=OWL_EDITWIN_STYLE_MULTILINE) &&
     
    69167}
    70168
    71 void owl_editwin_set_history(owl_editwin *e, owl_history *h)
    72 {
    73   e->hist=h;
    74 }
    75 
    76169owl_history *owl_editwin_get_history(owl_editwin *e)
    77170{
     
    84177}
    85178
    86 void owl_editwin_set_command(owl_editwin *e, char *command) {
     179void owl_editwin_set_command(owl_editwin *e, char *command)
     180{
    87181  if(e->command) owl_free(e->command);
    88182  e->command = owl_strdup(command);
    89183}
    90184
    91 char *owl_editwin_get_command(owl_editwin *e) {
     185char *owl_editwin_get_command(owl_editwin *e)
     186{
    92187  if(e->command) return e->command;
    93188  return "";
    94189}
    95190
    96 void owl_editwin_set_callback(owl_editwin *e, void (*cb)(owl_editwin*)) {
     191void owl_editwin_set_callback(owl_editwin *e, void (*cb)(owl_editwin*))
     192{
    97193  e->callback = cb;
    98194}
    99195
    100 void (*owl_editwin_get_callback(owl_editwin *e))(owl_editwin*) {
     196void (*owl_editwin_get_callback(owl_editwin *e))(owl_editwin*)
     197{
    101198  return e->callback;
    102199}
    103200
    104 void owl_editwin_set_cbdata(owl_editwin *e, void *data) {
     201void owl_editwin_set_cbdata(owl_editwin *e, void *data)
     202{
    105203  e->cbdata = data;
    106204}
    107205
    108 void* owl_editwin_get_cbdata(owl_editwin *e) {
     206void *owl_editwin_get_cbdata(owl_editwin *e) {
    109207  return e->cbdata;
    110208}
     
    121219}
    122220
    123 int owl_editwin_limit_maxcols(int v, int maxv)
    124 {
     221static int owl_editwin_limit_maxcols(int v, int maxv)
     222{
     223  /* maxv > 5 ? MAX(v, vax) : v */
    125224  if (maxv > 5 && v > maxv) {
    126225    return(maxv);
     
    135234void owl_editwin_set_locktext(owl_editwin *e, char *text)
    136235{
    137  
    138   int x, y;
    139 
    140   x=e->buffx;
    141   y=e->buffy;
    142   e->buffx=0;
    143   e->buffy=0;
    144   owl_editwin_overwrite_string(e, text);
    145   owl_editwin_overwrite_char(e, '\0');
    146   e->lock=strlen(text);
    147   /* if (text[e->lock-1]=='\n') e->lock--; */
    148   /*  e->buffx=x; */
    149   /*  e->buffy=y; */
    150   _owl_editwin_set_xy_by_index(e, e->lock);
     236  oe_set_index(e, 0);
     237  e->lock = 0;
     238  owl_editwin_replace(e, e->bufflen, text);
     239  e->buff[e->bufflen] = 0;
     240  e->lock=e->bufflen;
     241  oe_set_index(e, e->lock);
    151242  owl_editwin_redisplay(e, 0);
    152243}
     
    159250void owl_editwin_new_style(owl_editwin *e, int newstyle, owl_history *h)
    160251{
    161   char *ptr;
    162 
    163   owl_editwin_set_history(e, h);
     252  e->hist = h;
     253
    164254  if (e->style==newstyle) return;
    165255
     
    170260
    171261    /* nuke everything after the first line */
    172     if (e->bufflen > 0) {
    173       ptr=strchr(e->buff, '\n')-1;
    174       if (ptr) {
    175         e->bufflen=ptr - e->buff;
    176         e->buff[e->bufflen]='\0';
    177         e->buffx=0;
    178         e->buffy=0;
    179       }
    180     }
     262    owl_editwin_move_to_top(e);
     263    owl_editwin_move_to_end_of_line(e);
     264    owl_editwin_replace(e, oe_count_glyphs(e->buff + e->index),  "");
    181265  }
    182266}
     
    195279{
    196280
    197   int lock;
     281  int lock = e->lock;
    198282  int dotsend=e->dotsend;
    199283  char *locktext=NULL;
    200284  char echochar=e->echochar;
    201285
    202   lock=0;
    203   if (e->lock > 0) {
    204     lock=1;
    205 
    206     locktext=owl_malloc(e->lock+20);
    207     strncpy(locktext, e->buff, e->lock);
    208     locktext[e->lock]='\0';
     286  if (lock > 0) {
     287    locktext = owl_malloc(lock+1);
     288    strncpy(locktext, e->buff, lock);
     289    locktext[lock] = 0;
    209290  }
    210291
     
    222303  }
    223304
    224   if (locktext) owl_free(locktext);
    225   owl_editwin_adjust_for_locktext(e);
    226 }
    227 
    228 /* malloc more space for the buffer */
    229 void _owl_editwin_addspace(owl_editwin *e)
    230 {
    231   e->buff=owl_realloc(e->buff, e->allocated+INCR);
    232   if (!e->buff) {
    233     /* error */
    234     return;
    235   }
    236   e->allocated+=INCR;
     305  if (locktext)
     306    owl_free(locktext);
     307
     308  oe_set_index(e, lock);
    237309}
    238310
    239311void owl_editwin_recenter(owl_editwin *e)
    240312{
    241   e->topline=e->buffy-(e->winlines/2);
    242   if (e->topline<0) e->topline=0;
    243   if (e->topline>owl_editwin_get_numlines(e)) e->topline=owl_editwin_get_numlines(e);
     313  e->topindex = -1;
     314}
     315
     316static void oe_save_excursion(owl_editwin *e, oe_excursion *x)
     317{
     318  x->index = e->index;
     319  x->mark = e->mark;
     320  x->goal_column = e->goal_column;
     321  x->lock = e->lock;
     322
     323  x->valid = VALID_EXCURSION;
     324  x->next = e->excursions;
     325  e->excursions = x;
     326}
     327
     328static void oe_release_excursion(owl_editwin *e, oe_excursion *x)
     329{
     330  oe_excursion *p;
     331
     332  x->valid = 0;
     333  if (e->excursions == NULL)
     334    /* XXX huh. */ ;
     335  else if (e->excursions == x)
     336    e->excursions = x->next;
     337  else {
     338    for (p = e->excursions; p->next != NULL; p = p->next)
     339      if (p->next == x) {
     340        p->next = p->next->next;
     341        break;
     342      }
     343    /* and if we ran off the end? XXX */
     344  }
     345}
     346
     347static void oe_restore_excursion(owl_editwin *e, oe_excursion *x)
     348{
     349  if (x->valid == VALID_EXCURSION) {
     350    oe_set_index(e, x->index);
     351    e->goal_column = x->goal_column;
     352    e->mark = x->mark;
     353    e->lock = x->lock;
     354
     355    oe_release_excursion(e, x);
     356  }
     357}
     358
     359static void oe_restore_mark_only(owl_editwin *e, oe_excursion *x)
     360{
     361  if (x->valid == VALID_EXCURSION) {
     362    e->mark = x->mark;
     363
     364    oe_release_excursion(e, x);
     365  }
     366}
     367
     368/* External interface to oe_save_excursion */
     369owl_editwin_excursion *owl_editwin_begin_excursion(owl_editwin *e)
     370{
     371  owl_editwin_excursion *x = owl_malloc(sizeof *x);
     372  oe_save_excursion(e, x);
     373  return x;
     374}
     375
     376void owl_editwin_end_excursion(owl_editwin *e, owl_editwin_excursion *x)
     377{
     378  oe_restore_excursion(e, x);
     379  owl_free(x);
     380}
     381
     382static inline char *oe_next_point(owl_editwin *e, char *p)
     383{
     384  char *boundary = e->buff + e->bufflen + 1;
     385  char *q;
     386
     387  q = g_utf8_find_next_char(p, boundary);
     388  while (q && g_unichar_ismark(g_utf8_get_char(q)))
     389    q = g_utf8_find_next_char(q, boundary);
     390
     391  if (q == p)
     392    return NULL;
     393  return q;
     394}
     395
     396static inline char *oe_prev_point(owl_editwin *e, char *p)
     397{
     398  char *boundary = e->buff + e->lock;
     399
     400  p = g_utf8_find_prev_char(boundary, p);
     401  while (p && g_unichar_ismark(g_utf8_get_char(p)))
     402    p = g_utf8_find_prev_char(boundary, p);
     403
     404  return p;
     405}
     406
     407static int oe_char_width(gunichar c, int column)
     408{
     409  int cw;
     410
     411  if (c == 9) /* TAB */
     412    return TABSIZE - column % TABSIZE;
     413
     414  cw = mk_wcwidth(c);
     415
     416  if (cw < 0) /* control characters */
     417    cw = 0;
     418
     419  return cw;
     420}
     421
     422static int oe_find_display_line(owl_editwin *e, int *x, int index)
     423{
     424  int width = 0, cw;
     425  gunichar c;
     426  char *p;
     427
     428  while(1) {
     429    /* note the position of the dot */
     430    if (x != NULL && index == e->index && width < e->wincols)
     431      *x = width;
     432
     433    /* get the current character */
     434    c = g_utf8_get_char(e->buff + index);
     435
     436    /* figure out how wide it is */
     437    cw = oe_char_width(c, width);
     438
     439    if (width + cw > e->wincols) {
     440      if (x != NULL && *x == width)
     441        *x = -1;
     442      break;
     443    }
     444    width += cw;
     445
     446    if (c == '\n') {
     447      if (width < e->wincols)
     448        ++index; /* skip the newline */
     449      break;
     450    }
     451
     452    /* find the next character */
     453    p = oe_next_point(e, e->buff + index);
     454    if (p == NULL) { /* we ran off the end */
     455      if (x != NULL && e->index > index)
     456        *x = width + 1;
     457      break;
     458    }
     459    index = p - e->buff;
     460
     461  }
     462  return index;
     463}
     464
     465static void oe_reframe(owl_editwin *e) {
     466  oe_excursion x;
     467  int goal = e->winlines / 2;
     468  int index;
     469  int count = 0;
     470  int point;
     471  int n, i;
     472  int last;
     473
     474  oe_save_excursion(e, &x);
     475  /* step back line-by-line through the buffer until we have >= goal lines of
     476     display text */
     477  e->lock = 0; /* we can (must) tread on the locktext */
     478
     479  point = e->index;
     480  last = -1;
     481  while (count < goal) {
     482    index = e->index;
     483    owl_editwin_move_to_beginning_of_line(e);
     484    if (last == e->index)
     485      break;
     486    last = e->index;
     487    for (n = 0, i = e->index; i < index; n++)
     488      i = oe_find_display_line(e, NULL, i);
     489    count += n == 0 ? 1 : n;
     490    if (count < goal)
     491      owl_editwin_point_move(e, -1);
     492  }
     493
     494  e->topindex = e->index;
     495  /* if we overshot, backtrack */
     496  for (n = 0; n < (count - goal); n++)
     497    e->topindex = oe_find_display_line(e, NULL, e->topindex);
     498
     499  oe_restore_excursion(e, &x);
     500}
     501
     502static void oe_addnec(owl_editwin *e, int count)
     503{
     504  int i;
     505
     506  for (i = 0; i < count; i++)
     507    waddch(e->curswin, e->echochar);
     508}
     509
     510static void oe_mvaddnec(owl_editwin *e, int y, int x, int count)
     511{
     512  wmove(e->curswin, y, x);
     513  oe_addnec(e, count);
    244514}
    245515
     
    248518void owl_editwin_redisplay(owl_editwin *e, int update)
    249519{
    250  
    251   char *ptr1, *ptr2, *ptr3, *buff;
    252   int i;
    253 
    254   werase(e->curswin);
    255   wmove(e->curswin, 0, 0);
    256 
    257   /* start at topline */
    258   ptr1 = e->buff;
    259   for (i = 0; i < e->topline; i++) {
    260     ptr2 = strchr(ptr1, '\n');
    261     if (!ptr2) {
    262       /* we're already on the last line */
    263       break;
     520  int x = -1, y = -1, t;
     521  int line, index, lineindex, times = 0;
     522
     523  do {
     524    werase(e->curswin);
     525
     526    if (e->topindex == -1 || e->index < e->topindex)
     527      oe_reframe(e);
     528
     529    line = 0;
     530    index = e->topindex;
     531    while(line < e->winlines) {
     532      lineindex = index;
     533      t = -1;
     534      index = oe_find_display_line(e, &t, lineindex);
     535      if (x == -1 && t != -1)
     536        x = t, y = line;
     537      if (index - lineindex) {
     538        if (!e->echochar)
     539          mvwaddnstr(e->curswin, line, 0,
     540                     e->buff + lineindex,
     541                     index - lineindex);
     542        else {
     543          if(lineindex < e->lock) {
     544            mvwaddnstr(e->curswin, line, 0,
     545                       e->buff + lineindex,
     546                       MIN(index - lineindex,
     547                           e->lock - lineindex));
     548            if (e->lock < index)
     549              oe_addnec(e,
     550                        oe_region_width(e, e->lock, index,
     551                                        oe_region_width(e, lineindex, e->lock, 0)));
     552          } else
     553            oe_mvaddnec(e, line, 0, oe_region_width(e, line, index, 0));
     554        }
     555      }
     556      line++;
    264557    }
    265     ptr1 = ptr2 + 1;
    266   }
    267   /* ptr1 now stores the starting point */
    268 
    269   /* find the ending point and store it in ptr3 */
    270   ptr2 = ptr1;
    271   ptr3 = ptr1;
    272   for (i = 0; i < e->winlines; i++) {
    273     ptr3 = strchr(ptr2, '\n');
    274     if (!ptr3) {
    275       /* we've hit the last line */
    276       /* print everything to the end */
    277       ptr3 = e->buff + e->bufflen - 1;
    278       ptr3--;
    279       break;
     558    if (x == -1)
     559        e->topindex = -1; /* force a reframe */
     560    times++;
     561  } while(x == -1 && times < 3);
     562
     563  wmove(e->curswin, y, x);
     564  e->cursorx = x;
     565
     566  wnoutrefresh(e->curswin);
     567  if (update == 1)
     568    doupdate();
     569}
     570
     571static inline void oe_fixup(int *target, int start, int end, int change) {
     572  if (*target > start) {
     573    if (*target < end)
     574      *target = end;
     575    else
     576      *target += change;
     577  }
     578}
     579
     580int owl_editwin_replace_region(owl_editwin *e, char *s)
     581{
     582  oe_excursion x;
     583  oe_save_excursion(e, &x);
     584  int ret;
     585
     586  if(e->index > e->mark) {
     587    owl_editwin_exchange_point_and_mark(e);
     588  }
     589
     590  ret = owl_editwin_replace_internal(e, e->mark - e->index, s);
     591
     592  oe_restore_excursion(e, &x);
     593
     594  return ret;
     595}
     596
     597/* replace 'replace' characters at the point with s, returning the change in size */
     598int owl_editwin_replace(owl_editwin *e, int replace, char *s)
     599{
     600  int start, end, i;
     601  char *p;
     602
     603  if (!g_utf8_validate(s, -1, NULL)) {
     604    owl_function_debugmsg("owl_editwin_insert_string: received non-utf-8 string.");
     605    return 0;
     606  }
     607
     608  start = e->index;
     609  for (i = 0, p = e->buff + start; i < replace && p != NULL; i++)
     610    p = oe_next_point(e, p);
     611  if (p != NULL)
     612    end = p - e->buff;
     613  else
     614    end = e->bufflen;
     615
     616  return owl_editwin_replace_internal(e, end - start, s);
     617}
     618
     619static int owl_editwin_replace_internal(owl_editwin *e, int replace, char *s)
     620{
     621  int start, end, free, need, size, change;
     622  oe_excursion *x;
     623  char *p;
     624
     625  start = e->index;
     626  end   = start + replace;
     627
     628  free = e->allocated - e->bufflen + end - start;
     629
     630  need = strlen(s) - free;
     631  if (need > 0) {
     632    size = e->allocated + need + INCR - (need % INCR);
     633    p = owl_realloc(e->buff, size);
     634    if (p == NULL) {
     635      /* XXX signal impending doom somehow and don't do anything */
     636      return 0;
    280637    }
    281     ptr2 = ptr3 + 1;
    282   }
    283   ptr3 += 2;
    284 
    285   buff = owl_malloc(ptr3 - ptr1 + 50);
    286   strncpy(buff, ptr1, ptr3 - ptr1);
    287   buff[ptr3 - ptr1] = '\0';
    288   if (e->echochar == '\0') {
    289     waddstr(e->curswin, buff);
    290   } else {
    291     /* translate to echochar, *except* for the locktext */
    292     int len;
    293     int dolocklen = e->lock - (ptr1 - e->buff);
    294     char *locktext;
    295     char tmp = e->buff[dolocklen];
    296 
    297     e->buff[dolocklen] = '\0';
    298     locktext = owl_strdup(e->buff);
    299     e->buff[dolocklen] = tmp;
    300 
    301     waddstr(e->curswin, locktext);
    302    
    303     len = strlen(buff);
    304     for (i = 0; i < len-dolocklen; i++) {
    305       waddch(e->curswin, e->echochar);
    306     }
    307   }
    308   wmove(e->curswin, e->buffy-e->topline, e->buffx + _owl_editwin_cursor_adjustment(e));
    309   wnoutrefresh(e->curswin);
    310   if (update == 1) {
    311     doupdate();
    312   }
    313   owl_free(buff);
    314 }
    315 
    316 /* Remove n bytes at cursor. */
    317 void _owl_editwin_remove_bytes(owl_editwin *e, int n) /*noproto*/
    318 {
    319   int i = _owl_editwin_get_index_from_xy(e) + n;
    320   for (; i < e->bufflen; i++) {
    321     e->buff[i-n] = e->buff[i];
    322   }
    323  
    324   e->bufflen -= n;
    325   e->buff[e->bufflen] = '\0';
    326 }
    327 
    328 /* Insert n bytes at cursor.*/
    329 void _owl_editwin_insert_bytes(owl_editwin *e, int n) /*noproto*/
    330 {
    331   int i, z;
    332 
    333   if ((e->bufflen + n) > (e->allocated - 5)) {
    334     _owl_editwin_addspace(e);
    335   }
    336 
    337   z = _owl_editwin_get_index_from_xy(e);
    338 
    339   if(z != e->bufflen) {
    340     for (i = e->bufflen + n - 1; i > z; i--) {
    341       e->buff[i] = e->buff[i - n];
    342     }
    343   }
    344 
    345   e->bufflen += n;
    346   e->buff[e->bufflen] = '\0';
    347 
    348 }
    349 
     638    e->buff = p;
     639    e->allocated = size;
     640  }
     641
     642  memmove(e->buff + start + strlen(s), e->buff + end, e->bufflen + 1 - end);
     643  memcpy(e->buff + start, s, strlen(s));
     644  change = start - end + strlen(s);
     645  e->bufflen += change;
     646  e->index += strlen(s);
     647
     648  /* fix up the mark */
     649  oe_fixup(&e->mark, start, end, change);
     650  oe_fixup(&e->topindex, start, end, change);
     651  /* fix up any saved points after the replaced area */
     652  for (x = e->excursions; x != NULL; x = x->next) {
     653    oe_fixup(&x->index, start, end, change);
     654    oe_fixup(&x->mark, start, end, change);
     655  }
     656
     657  return change;
     658}
    350659
    351660/* linewrap the word just before the cursor.
     
    353662 * returns -1 if we could not wrap.
    354663 */
    355 int _owl_editwin_linewrap_word(owl_editwin *e)
    356 {
    357   int x, y;
    358   int i;
    359   char *ptr1, *start;
     664static void _owl_editwin_linewrap_word(owl_editwin *e)
     665{
     666  oe_excursion x;
    360667  gunichar c;
    361668
    362   /* saving values */
    363   x = e->buffx;
    364   y = e->buffy;
    365   start = e->buff + e->lock;
    366 
    367   ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
    368   ptr1 = g_utf8_find_prev_char(start, ptr1);
    369 
    370   while (ptr1) {
    371     c = g_utf8_get_char(ptr1);
    372     if (owl_util_can_break_after(c)) {
    373       if (c != ' ') {
    374         i = ptr1 - e->buff;
    375         _owl_editwin_set_xy_by_index(e, i);
    376         _owl_editwin_insert_bytes(e, 1);
    377         /* _owl_editwin_insert_bytes may move e->buff. */
    378         ptr1 = e->buff + i;
    379       }
    380       *ptr1 = '\n';
    381       return 0;
     669  oe_save_excursion(e, &x);
     670
     671  while (owl_editwin_point_move(e, -1)) {
     672    c = owl_editwin_get_char_at_point(e);
     673    if (owl_util_can_break_after(c) || c == '\n') {
     674      if (c != '\n')
     675        owl_editwin_replace(e, c != ' ' ? 0 : 1, "\n");
     676      break;
    382677    }
    383     else if (c == '\n') {
    384       return 0;
    385     }
    386     ptr1 = g_utf8_find_prev_char(start, ptr1);
    387   }
    388   return -1;
    389 }
    390 
    391 /* insert a character at the current point (shift later
    392  * characters over)
    393  */
    394 void owl_editwin_insert_char(owl_editwin *e, gunichar c)
    395 {
    396   int z, i, ret, len;
    397   char tmp[6];
    398   memset(tmp, '\0', 6);
    399 
    400   /* \r is \n */
    401   if (c == '\r') {
    402     c = '\n';
    403   }
    404 
    405   if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
    406     /* perhaps later this will change some state that allows the string
    407        to be read */
    408     return;
    409   }
    410 
    411   g_unichar_to_utf8(c, tmp);
    412   len = strlen(tmp);
    413 
    414   /* make sure there is enough memory for the new text */
    415   if ((e->bufflen + len) > (e->allocated - 5)) {
    416     _owl_editwin_addspace(e);
    417   }
    418 
    419   /* get the insertion point */
    420   z = _owl_editwin_get_index_from_xy(e);
    421 
    422   /* If we're going to insert at the last column do word wrapping, unless it's a \n */
    423   if ((e->buffx + 1 == e->wrapcol) && (c != '\n')) {
    424     ret = _owl_editwin_linewrap_word(e);
    425     if (ret == -1) {
    426       /* we couldn't wrap, insert a hard newline instead */
    427       owl_editwin_insert_char(e, '\n');
    428     }
    429   }
    430 
    431   /* shift all the other characters right */
    432   _owl_editwin_insert_bytes(e, len);
    433 
    434   /* insert the new character */
    435   for(i = 0; i < len; i++) {
    436     e->buff[z + i] = tmp[i];
    437   }
    438 
    439   /* advance the cursor */
    440   z += len;
    441   _owl_editwin_set_xy_by_index(e, z);
    442 }
    443 
    444 /* overwrite the character at the current point with 'c' */
    445 void owl_editwin_overwrite_char(owl_editwin *e, gunichar c)
    446 {
    447   int z, oldlen, newlen, i;
    448   char tmp[6];
    449   memset(tmp, '\0', 6);
    450 
    451   /* \r is \n */
    452   if (c == '\r') {
    453     c = '\n';
    454   }
    455  
    456   if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
    457     /* perhaps later this will change some state that allows the string
    458        to be read */
    459     return;
    460   }
    461 
    462   g_unichar_to_utf8(c, tmp);
    463   newlen = strlen(tmp);
    464 
    465   z = _owl_editwin_get_index_from_xy(e);
    466   {
    467     char *t = g_utf8_find_next_char(e->buff + z, NULL);
    468     oldlen = (t ? (t - (e->buff + z)) : 0);
    469   }
    470 
    471   /* only if we are at the end of the buffer do we create new space here */
    472   if (z == e->bufflen) {
    473     if ((e->bufflen+newlen) > (e->allocated-5)) {
    474       _owl_editwin_addspace(e);
    475     }
    476   }
    477   /* if not at the end of the buffer, adjust based in char size difference. */
    478   else if (oldlen > newlen) {
    479     _owl_editwin_remove_bytes(e, oldlen-newlen);
    480   }
    481   else /* oldlen < newlen */ {
    482     _owl_editwin_insert_bytes(e, newlen-oldlen);
    483   }
    484   /* Overwrite the old char*/
    485   for (i = 0; i < newlen; i++) {
    486     e->buff[z+i] = tmp[i];
    487   }
    488        
    489   /* housekeeping */
    490   if (z == e->bufflen) {
    491     e->bufflen += newlen;
    492     e->buff[e->bufflen] = '\0';
    493   }
    494  
    495   /* advance the cursor */
    496   z += newlen;
    497   _owl_editwin_set_xy_by_index(e, z);
     678  }
     679
     680  oe_restore_excursion(e, &x);
    498681}
    499682
    500683/* delete the character at the current point, following chars
    501684 * shift left.
    502  */ 
     685 */
    503686void owl_editwin_delete_char(owl_editwin *e)
    504687{
    505   int z;
    506   char *p1, *p2;
    507   gunichar c;
    508 
    509   if (e->bufflen == 0) return;
    510  
    511   /* get the deletion point */
    512   z = _owl_editwin_get_index_from_xy(e);
    513 
    514   if (z == e->bufflen) return;
    515 
    516   p1 = e->buff + z;
    517   p2 = g_utf8_next_char(p1);
    518   c = g_utf8_get_char(p2);
    519   while (g_unichar_ismark(c)) {
    520     p2 = g_utf8_next_char(p2);
    521     c = g_utf8_get_char(p2);
    522   }
    523   _owl_editwin_remove_bytes(e, p2-p1);
     688  owl_editwin_replace(e, 1, "");
    524689}
    525690
     
    527692 * advance the pointer.  If point is at beginning of buffer do
    528693 * nothing.  If point is after the last character swap point-1 with
    529  * point-2.  (Behaves as observed in tcsh and emacs). 
     694 * point-2.  (Behaves as observed in tcsh and emacs).
    530695 */
    531696void owl_editwin_transpose_chars(owl_editwin *e)
    532697{
    533   int z;
    534   char *p1, *p2, *p3, *tmp;
     698  char *middle, *end, *start, *tmp;
    535699
    536700  if (e->bufflen == 0) return;
    537  
    538   /* get the cursor point */
    539   z = _owl_editwin_get_index_from_xy(e);
    540 
    541   if (z == e->bufflen) {
    542     /* point is after last character */
    543     z--;
    544   } 
    545 
    546   if (z - 1 < e->lock) {
    547     /* point is at beginning of buffer, do nothing */
     701
     702  if (e->index == e->bufflen)
     703    owl_editwin_point_move(e, -1);     /* point is after last character */
     704
     705  if (owl_editwin_at_beginning_of_buffer(e))
     706    return;     /* point is at beginning of buffer, do nothing */
     707
     708  /* Transpose two utf-8 unicode glyphs. */
     709  middle = e->buff + e->index;
     710
     711  end = oe_next_point(e, middle);
     712  if (end == NULL)
    548713    return;
    549   }
    550 
    551   /* Transpose two utf-8 unicode glyphs. */
    552   p1 = e->buff + z;
    553 
    554   p2 = g_utf8_find_next_char(p1, NULL);
    555   while (p2 != NULL && g_unichar_ismark(g_utf8_get_char(p2))) {
    556     p2 = g_utf8_find_next_char(p2, NULL);
    557   }
    558   if (p2 == NULL) return;
    559 
    560   p3 = g_utf8_find_prev_char(e->buff, p1);
    561   while (p3 != NULL && g_unichar_ismark(g_utf8_get_char(p3))) {
    562     p3 = g_utf8_find_prev_char(p3, NULL);
    563   }
    564   if (p3 == NULL) return;
    565 
    566   tmp = owl_malloc(p2 - p3 + 5);
    567   *tmp = '\0';
    568   strncat(tmp, p1, p2 - p1);
    569   strncat(tmp, p3, p1 - p3);
    570   strncpy(p3, tmp, p2 - p3);
    571   owl_free(tmp);
    572   _owl_editwin_set_xy_by_index(e, p3 - e->buff);
     714
     715  start = oe_prev_point(e, middle);
     716  if (start == NULL)
     717    return;
     718
     719  tmp = owl_malloc((end - start) + 1);
     720  tmp[(end - start)] = 0;
     721  memcpy(tmp, middle, end - middle);
     722  memcpy(tmp + (end - middle), start, middle - start);
     723
     724  owl_editwin_point_move(e, -1);
     725  owl_editwin_replace(e, 2, tmp);
    573726}
    574727
     
    576729 * right
    577730 */
    578 void owl_editwin_insert_string(owl_editwin *e, char *string)
     731void owl_editwin_insert_string(owl_editwin *e, char *s)
     732{
     733  owl_editwin_replace(e, 0, s);
     734}
     735
     736/* We assume index is not set to point to a mid-char */
     737static gunichar owl_editwin_get_char_at_point(owl_editwin *e)
     738{
     739  return g_utf8_get_char(e->buff + e->index);
     740}
     741
     742void owl_editwin_exchange_point_and_mark(owl_editwin *e) {
     743  int tmp;
     744
     745  if (e->mark != -1) {
     746    tmp = e->mark;
     747    owl_editwin_set_mark(e);
     748    oe_set_index(e, tmp);
     749  }
     750}
     751
     752int owl_editwin_point_move(owl_editwin *e, int delta)
    579753{
    580754  char *p;
    581   gunichar c;
    582   if (!g_utf8_validate(string, -1, NULL)) {
    583     owl_function_debugmsg("owl_editwin_insert_string: received non-utf-8 string.");
    584     return;
    585   }
    586   p = string;
    587   c = g_utf8_get_char(p);
    588   while (c) {
    589     _owl_editwin_process_char(e, c);
    590     p = g_utf8_next_char(p);
    591     c = g_utf8_get_char(p);
    592   }
    593 }
    594 
    595 /* write 'string' at the current point, overwriting text that is
    596  * already there
    597  */
    598 
    599 void owl_editwin_overwrite_string(owl_editwin *e, char *string)
     755  int change, d = 0;
     756
     757  change = MAX(delta, - delta);
     758  p = e->buff + e->index;
     759
     760  while (d < change && p != NULL) {
     761    if (delta > 0)
     762      p = oe_next_point(e, p);
     763    else
     764      p = oe_prev_point(e, p);
     765    if (p != NULL) {
     766      oe_set_index(e, p - e->buff);
     767      d++;
     768    }
     769  }
     770
     771  return delta > 0 ? d : -d;
     772}
     773
     774int owl_editwin_at_beginning_of_buffer(owl_editwin *e) {
     775  if (e->index == e->lock)
     776    return 1;
     777
     778  return 0;
     779}
     780
     781int owl_at_end_of_buffer(owl_editwin *e) {
     782  if (e->index == e->bufflen)
     783    return 1;
     784
     785  return 0;
     786}
     787
     788int owl_editwin_at_beginning_of_line(owl_editwin *e) /*noproto*/
     789{
     790  oe_excursion x;
     791  int ret;
     792
     793  if (owl_editwin_at_beginning_of_buffer(e))
     794    return 1;
     795
     796  oe_save_excursion(e, &x);
     797  owl_editwin_point_move(e, -1);
     798  ret = (owl_editwin_get_char_at_point(e) == '\n');
     799  oe_restore_excursion(e, &x);
     800
     801  return ret;
     802}
     803
     804static int owl_editwin_is_char_in(owl_editwin *e, char *set)
    600805{
    601806  char *p;
    602   gunichar c;
    603 
    604   if (!g_utf8_validate(string, -1, NULL)) {
    605     owl_function_debugmsg("owl_editwin_overwrite_string: received non-utf-8 string.");
    606     return;
    607   }
    608   p = string;
    609   c = g_utf8_get_char(p);
    610   while (c) {
    611     owl_editwin_overwrite_char(e, c);
    612     p = g_utf8_next_char(p);
    613     c = g_utf8_get_char(p);
    614   }
    615 }
    616 
    617 /* get the index into e->buff for the current cursor
    618  * position.
    619  */
    620 int _owl_editwin_get_index_from_xy(owl_editwin *e)
    621 {
    622   int i;
    623   char *ptr1, *ptr2;
    624   gunichar c;
    625 
    626   if (e->bufflen == 0) return(0);
    627  
    628   /* first go to the yth line */
    629   ptr1 = e->buff;
    630   for (i = 0; i < e->buffy; i++) {
    631     ptr2= strchr(ptr1, '\n');
    632     if (!ptr2) {
    633       /* we're already on the last line */
     807
     808  for (p = set; *p != 0; p = g_utf8_find_next_char(p, NULL))
     809    if (owl_editwin_get_char_at_point(e) == g_utf8_get_char(p))
     810      return 1;
     811  return 0;
     812}
     813
     814int owl_editwin_move_if_in(owl_editwin *e, int delta, char *set)
     815{
     816  int change, distance = 0;
     817  while (owl_editwin_is_char_in(e, set)) {
     818    change = owl_editwin_point_move(e, delta);
     819    distance += change;
     820    if (change == 0)
    634821      break;
     822  }
     823  return distance;
     824}
     825
     826int owl_editwin_move_if_not_in(owl_editwin *e, int delta, char *set)
     827{
     828  int change, distance = 0;
     829  while (!owl_editwin_is_char_in(e, set)) {
     830    change = owl_editwin_point_move(e, delta);
     831    distance += change;
     832    if (change == 0)
     833      break;
     834  }
     835  return distance;
     836}
     837
     838int owl_editwin_move_to_beginning_of_line(owl_editwin *e)
     839{
     840  int distance = 0;
     841
     842  if (!owl_editwin_at_beginning_of_line(e)) {
     843    /* move off the \n if were at the end of a line */
     844    distance += owl_editwin_point_move(e, -1);
     845    distance += owl_editwin_move_if_not_in(e, -1, "\n");
     846    if (distance && !owl_editwin_at_beginning_of_buffer(e))
     847      distance += owl_editwin_point_move(e, 1);
     848  }
     849  e->goal_column = 0; /* subtleties */
     850
     851  return distance;
     852}
     853
     854int owl_editwin_move_to_end_of_line(owl_editwin *e)
     855{
     856  return owl_editwin_move_if_not_in(e, 1, "\n");
     857}
     858
     859int owl_editwin_line_move(owl_editwin *e, int delta)
     860{
     861  int goal_column, change, ll, distance;
     862  int count = 0;
     863
     864  change = MAX(delta, -delta);
     865
     866  goal_column = e->goal_column;
     867  distance = owl_editwin_move_to_beginning_of_line(e);
     868  goal_column = goal_column == -1 ? -distance : goal_column;
     869
     870  while(count < change) {
     871    if (delta > 0) {
     872      distance += owl_editwin_move_if_not_in(e, 1, "\n");
     873      distance += owl_editwin_point_move(e, 1);
     874    } else {
     875      /* I really want to assert delta < 0 here */
     876      distance += owl_editwin_point_move(e, -1); /* to the newline on
     877                                                    the previous line */
     878      distance += owl_editwin_move_to_beginning_of_line(e);
    635879    }
    636     ptr1 = ptr2 + 1;
    637   }
    638 
    639   /* now go to the xth cell */
    640   ptr2 = ptr1;
    641   i = 0;
    642   while (ptr2 != NULL && i < e->buffx && (ptr2 - e->buff) < e->bufflen) {
    643     c = g_utf8_get_char(ptr2);
    644     i += (c == '\n' ? 1 : mk_wcwidth(c));
    645     ptr2 = g_utf8_next_char(ptr2);
    646   }
    647   while(ptr2 != NULL && g_unichar_ismark(g_utf8_get_char(ptr2))) {
    648     ptr2 = g_utf8_next_char(ptr2);
    649   }
    650   if (ptr2 == NULL) return e->bufflen;
    651   return(ptr2 - e->buff);
    652 }
    653 
    654 /* We assume x,y are not set to point to a mid-char */
    655 gunichar _owl_editwin_get_char_at_xy(owl_editwin *e)
    656 {
    657   return g_utf8_get_char(e->buff + _owl_editwin_get_index_from_xy(e));
    658 }
    659 
    660 
    661 void _owl_editwin_set_xy_by_index(owl_editwin *e, int index)
    662 {
    663   char *ptr1, *ptr2, *target;
    664   gunichar c;
    665 
    666   e->buffx = 0;
    667   e->buffy = 0;
    668 
    669   ptr1 = e->buff;
    670   target = ptr1 + index;
    671   /* target sanitizing */
    672   if ((target[0] & 0x80) && (~target[0] & 0x40)) {
    673     /* middle of a utf-8 character, back up to previous character. */
    674     target = g_utf8_find_prev_char(e->buff, target);
    675   }
    676   c = g_utf8_get_char(target);
    677   while (g_unichar_ismark(c) && target > e->buff) {
    678     /* Adjust the target off of combining characters and the like. */
    679     target = g_utf8_find_prev_char(e->buff, target);
    680     c = g_utf8_get_char(target);
    681   }
    682   /* If we start with a mark, something is wrong.*/
    683   if (g_unichar_ismark(c)) return;
    684 
    685   /* Now our target should be acceptable. */
    686   ptr2 = strchr(ptr1, '\n');
    687   while (ptr2 != NULL && ptr2 < target) {
    688     e->buffy++;
    689     ptr1 = ptr2 + 1;
    690     ptr2 = strchr(ptr1, '\n');
    691   }
    692   ptr2 = ptr1;
    693   while (ptr2 != NULL && ptr2 < target) {
    694     c = g_utf8_get_char(ptr2);
    695     e->buffx += mk_wcwidth(c);
    696     ptr2 = g_utf8_next_char(ptr2);
    697   }
    698 }
    699 
    700 int _owl_editwin_cursor_adjustment(owl_editwin *e)
    701 {
    702   char *ptr1, *ptr2;
    703   gunichar c;
    704   int x, i;
    705 
    706   /* Find line */
    707   ptr1 = e->buff;
    708   ptr2 = strchr(ptr1, '\n');
    709   for (i = 0; ptr2 != NULL && i < e->buffy; i++) {
    710     ptr1 = ptr2 + 1;
    711     ptr2 = strchr(ptr1, '\n');
    712   }
    713   ptr2 = ptr1;
    714 
    715   /* Find char */
    716   x = 0;
    717   while (ptr2 != NULL && x < e->buffx) {
    718     if (*ptr2 == '\n') return 0;
    719     c = g_utf8_get_char(ptr2);
    720     x += mk_wcwidth(c);
    721     ptr2 = g_utf8_next_char(ptr2);
    722   }
    723  
    724   /* calculate x offset */
    725   return x - e->buffx;
    726 }
    727 
    728 void owl_editwin_adjust_for_locktext(owl_editwin *e)
    729 {
    730   /* if we happen to have the cursor over locked text
    731    * move it to be out of the locktext region */
    732   if (_owl_editwin_get_index_from_xy(e) < e->lock) {
    733     _owl_editwin_set_xy_by_index(e, e->lock);
    734   }
     880    count++;
     881  }
     882
     883  distance += (ll = owl_editwin_move_to_end_of_line(e));
     884  if (ll > goal_column)
     885    distance += owl_editwin_point_move(e, goal_column - ll);
     886
     887  e->goal_column = goal_column;
     888
     889  return distance;
    735890}
    736891
     
    740895   * and shift later chars left
    741896   */
    742   if (_owl_editwin_get_index_from_xy(e) > e->lock) {
    743     owl_editwin_key_left(e);
     897  if(owl_editwin_point_move(e, -1))
    744898    owl_editwin_delete_char(e);
    745   }
    746   owl_editwin_adjust_for_locktext(e);
    747899}
    748900
    749901void owl_editwin_key_up(owl_editwin *e)
    750902{
    751   if (e->buffy > 0) e->buffy--;
    752   if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
    753     e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    754   }
    755 
    756   /* do we need to scroll? */
    757   if (e->buffy-e->topline < 0) {
    758     e->topline-=e->winlines/2;
    759   }
    760 
    761   owl_editwin_adjust_for_locktext(e);
     903  owl_editwin_line_move(e, -1);
    762904}
    763905
    764906void owl_editwin_key_down(owl_editwin *e)
    765907{
    766   /* move down if we can */
    767   if (e->buffy+1 < owl_editwin_get_numlines(e)) e->buffy++;
    768 
    769   /* if we're past the last character move back */
    770   if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
    771     e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    772   }
    773 
    774   /* do we need to scroll? */
    775   if (e->buffy-e->topline > e->winlines) {
    776     e->topline+=e->winlines/2;
    777   }
    778 
    779   /* adjust for locktext */
    780   owl_editwin_adjust_for_locktext(e);
     908  owl_editwin_line_move(e, 1);
    781909}
    782910
    783911void owl_editwin_key_left(owl_editwin *e)
    784912{
    785   int i;
    786   char * p;
    787   i = _owl_editwin_get_index_from_xy(e);
    788   p = e->buff + i;
    789   p = g_utf8_find_prev_char(e->buff, p);
    790   while (p && g_unichar_ismark(g_utf8_get_char(p))) {
    791     p = g_utf8_find_prev_char(e->buff, p);
    792   }
    793   if (p == NULL) p = e->buff;
    794   _owl_editwin_set_xy_by_index(e, p - e->buff);
    795 
    796   if (e->buffy - e->topline < 0) {
    797     e->topline -= e->winlines / 2;
    798   }
    799 
    800   /* make sure to avoid locktext */
    801   owl_editwin_adjust_for_locktext(e);
     913  owl_editwin_point_move(e, -1);
    802914}
    803915
    804916void owl_editwin_key_right(owl_editwin *e)
    805917{
    806   int i;
    807   char * p;
    808   i = _owl_editwin_get_index_from_xy(e);
    809   p = e->buff + i;
    810   p = g_utf8_find_next_char(p, NULL);
    811   while (p && g_unichar_ismark(g_utf8_get_char(p))) {
    812     p = g_utf8_find_next_char(p, NULL);
    813   }
    814   if (p == NULL) {
    815     _owl_editwin_set_xy_by_index(e, e->bufflen);
    816   }
    817   else {
    818     _owl_editwin_set_xy_by_index(e, p - e->buff);
    819   }
    820 
    821   /* do we need to scroll down? */
    822   if (e->buffy - e->topline >= e->winlines) {
    823     e->topline += e->winlines / 2;
    824   }
     918  owl_editwin_point_move(e, 1);
     919}
     920
     921int owl_editwin_forward_word(owl_editwin *e)
     922{
     923  int distance;
     924  /* if we're starting on a space, find the first non-space */
     925  distance = owl_editwin_move_if_in(e, 1, WHITESPACE);
     926
     927  /* now find the end of this word */
     928  distance += owl_editwin_move_if_not_in(e, 1, WHITESPACE);
     929
     930  return distance;
    825931}
    826932
    827933void owl_editwin_move_to_nextword(owl_editwin *e)
    828934{
    829   int i, x;
    830   gunichar c = '\0';
    831 
    832   /* if we're starting on a space, find the first non-space */
    833   i=_owl_editwin_get_index_from_xy(e);
    834   if (e->buff[i]==' ') {
    835     for (x=i; x<e->bufflen; x++) {
    836       if (e->buff[x]!=' ' && e->buff[x]!='\n') {
    837         _owl_editwin_set_xy_by_index(e, x);
    838         break;
     935  owl_editwin_forward_word(e);
     936}
     937
     938/* go backwards to the last non-space character
     939 */
     940int owl_editwin_backward_word(owl_editwin *e)
     941{
     942  oe_excursion x;
     943  int distance = 0;
     944  int further = 0;
     945  int beginning;
     946  /* if in middle of word, beginning of word */
     947
     948  /* if at beginning of a word, find beginning of previous word */
     949
     950  if (owl_editwin_is_char_in(e, WHITESPACE)) {
     951    /* if in whitespace past end of word, find a word , the find the beginning*/
     952    distance += owl_editwin_move_if_in(e, -1, WHITESPACE); /* leaves us on the last
     953                                                              character of the word */
     954    oe_save_excursion(e, &x);
     955    /* are we at the beginning of a word? */
     956    owl_editwin_point_move(e, -1);
     957    beginning = owl_editwin_is_char_in(e, WHITESPACE);
     958    oe_restore_excursion(e, &x);
     959    if (beginning)
     960      return distance;
     961   } else {
     962    /* in the middle of the word; */
     963    oe_save_excursion(e, &x);
     964    further += owl_editwin_point_move(e, -1);
     965    if (owl_editwin_is_char_in(e, WHITESPACE)) { /* we were at the beginning */
     966      distance += owl_editwin_backward_word(e); /* previous case */
     967      oe_release_excursion(e, &x);
     968      return distance + further;
     969    } else {
     970      oe_restore_excursion(e, &x);
     971    }
     972  }
     973  distance += owl_editwin_move_if_not_in(e, -1, WHITESPACE);
     974  /* will go past */
     975  if (e->index > e->lock)
     976    distance += owl_editwin_point_move(e, 1);
     977  return distance;
     978}
     979
     980void owl_editwin_move_to_previousword(owl_editwin *e)
     981{
     982  owl_editwin_backward_word(e);
     983}
     984
     985void owl_editwin_delete_nextword(owl_editwin *e)
     986{
     987  oe_excursion x;
     988
     989  oe_save_excursion(e, &x);
     990  oe_set_mark(e, e->index);
     991  owl_editwin_forward_word(e);
     992  owl_editwin_kill_region(e);
     993  oe_restore_mark_only(e, &x);
     994}
     995
     996void owl_editwin_delete_previousword(owl_editwin *e)
     997{
     998  oe_excursion x;
     999
     1000  oe_save_excursion(e, &x);
     1001  oe_set_mark(e, e->index);
     1002  owl_editwin_backward_word(e);
     1003  owl_editwin_kill_region(e);
     1004  oe_restore_mark_only(e, &x);
     1005}
     1006
     1007void owl_editwin_move_to_line_end(owl_editwin *e)
     1008{
     1009  owl_editwin_move_to_end_of_line(e);
     1010}
     1011
     1012void owl_editwin_delete_to_endofline(owl_editwin *e)
     1013{
     1014  oe_excursion x;
     1015  int distance;
     1016
     1017  oe_save_excursion(e, &x);
     1018  owl_editwin_set_mark(e);
     1019  distance = owl_editwin_move_to_end_of_line(e);
     1020  if (distance)
     1021    owl_editwin_kill_region(e);
     1022  else
     1023    owl_editwin_replace(e, 1, "");
     1024  oe_restore_excursion(e, &x);
     1025}
     1026
     1027void owl_editwin_yank(owl_editwin *e)
     1028{
     1029  if (e->killbuf != NULL)
     1030    owl_editwin_replace(e, 0, e->killbuf);
     1031}
     1032
     1033static char *oe_copy_buf(owl_editwin *e, char *buf, int len)
     1034{
     1035  char *p;
     1036
     1037  p = owl_malloc(len + 1);
     1038
     1039  if (p != NULL) {
     1040    owl_free(e->killbuf);
     1041    e->killbuf = p;
     1042    memcpy(e->killbuf, buf, len);
     1043    e->killbuf[len] = 0;
     1044  }
     1045
     1046  return p;
     1047}
     1048
     1049static int oe_copy_region(owl_editwin *e)
     1050{
     1051  char *p;
     1052  int start, end;
     1053
     1054  if (e->mark == -1)
     1055    return 0;
     1056
     1057  start = MIN(e->index, e->mark);
     1058  end = MAX(e->index, e->mark);
     1059
     1060  p = oe_copy_buf(e, e->buff + start, end - start);
     1061  if (p != NULL)
     1062    return end - start;
     1063  return 0;
     1064}
     1065
     1066void owl_editwin_copy_region_as_kill(owl_editwin *e)
     1067{
     1068  oe_copy_region(e);
     1069}
     1070
     1071void owl_editwin_kill_region(owl_editwin *e)
     1072{
     1073  if (e->index > e->mark)
     1074    owl_editwin_exchange_point_and_mark(e);
     1075
     1076  owl_editwin_replace(e, oe_copy_region(e), "");
     1077}
     1078
     1079void owl_editwin_move_to_line_start(owl_editwin *e)
     1080{
     1081  owl_editwin_move_to_beginning_of_line(e);
     1082}
     1083
     1084void owl_editwin_move_to_end(owl_editwin *e)
     1085{
     1086  oe_set_index(e, e->bufflen);
     1087}
     1088
     1089void owl_editwin_move_to_top(owl_editwin *e)
     1090{
     1091  oe_set_index(e, e->lock);
     1092}
     1093
     1094void owl_editwin_backward_paragraph(owl_editwin *e)
     1095{
     1096  owl_editwin_point_move(e, -1);
     1097  for (; e->index >= e->lock; owl_editwin_point_move(e, -1)) {
     1098    if (e->index <= e->lock ||
     1099        ((e->buff[e->index] == '\n') && (e->buff[e->index - 1]=='\n')))
     1100      break;
     1101  }
     1102}
     1103
     1104void owl_editwin_forward_paragraph(owl_editwin *e)
     1105{
     1106  owl_editwin_point_move(e, 1);
     1107  /* scan forward to the start of the next paragraph */
     1108  for(; e->index < e->bufflen; owl_editwin_point_move(e, 1)) {
     1109    if (e->buff[e->index -1] == '\n' && e->buff[e->index] == '\n')
     1110      break;
     1111  }
     1112}
     1113
     1114int owl_editwin_current_column(owl_editwin *e)
     1115{
     1116  oe_excursion x;
     1117  int lineindex;
     1118
     1119  oe_save_excursion(e, &x);
     1120  owl_editwin_move_to_beginning_of_line(e);
     1121  lineindex = e->index;
     1122  oe_restore_excursion(e, &x);
     1123  return oe_region_width(e, lineindex, e->index, 0);
     1124}
     1125
     1126void owl_editwin_fill_paragraph(owl_editwin *e)
     1127{
     1128  oe_excursion x;
     1129  gunichar ch;
     1130  int sentence;
     1131
     1132  oe_save_excursion(e, &x);
     1133
     1134  /* Mark the end of the paragraph */
     1135  owl_editwin_forward_paragraph(e);
     1136  /* Skip the trailing newline */
     1137  owl_editwin_point_move(e, -1);
     1138  owl_editwin_set_mark(e);
     1139
     1140  owl_editwin_backward_paragraph(e);
     1141
     1142  /* Don't mess with the leading newline */
     1143  if (owl_editwin_get_char_at_point(e) == '\n')
     1144    owl_editwin_point_move(e, 1);
     1145
     1146  /*
     1147   * First pass: Scan forward replacing all series of spaces with ' '
     1148   * (or nothing after CJK ideograms)
     1149   */
     1150  sentence = 0;
     1151  for(;e->index < e->mark; owl_editwin_point_move(e, 1)) {
     1152    /* bail if we hit a trailing dot on the buffer */
     1153    if (strcmp(e->buff + e->index, "\n.") == 0) {
     1154      owl_editwin_set_mark(e);
     1155      break;
     1156    }
     1157
     1158    ch = owl_editwin_get_char_at_point(e);
     1159
     1160    if (owl_util_can_break_after(ch) || ch == '\n') {
     1161      if (g_unichar_isspace(ch)) {
     1162        owl_editwin_replace(e, 1, " ");
     1163      }
     1164
     1165      if (sentence && g_unichar_isspace(owl_editwin_get_char_at_point(e)))
     1166        owl_editwin_point_move(e, 1);
     1167
     1168      while(g_unichar_isspace(owl_editwin_get_char_at_point(e))
     1169            && e->index < e->mark) {
     1170        owl_editwin_delete_char(e);
    8391171      }
    8401172    }
    841   }
    842 
    843   /* find the next space, newline or end of line and go
    844      there, if already at the end of the line, continue on to the next */
    845   i=owl_editwin_get_numcells_on_line(e, e->buffy);
    846   c = _owl_editwin_get_char_at_xy(e);
    847   if (e->buffx < i) {
    848     /* move right till end of line */
    849     while (e->buffx < i) {
    850       owl_editwin_key_right(e);
    851       c = _owl_editwin_get_char_at_xy(e);
    852       if (c == ' ') return;
    853       if (e->buffx == i) return;
    854     }
    855   } else if (e->buffx == i) {
    856     /* try to move down */
    857     if (e->style==OWL_EDITWIN_STYLE_MULTILINE) {
    858       if (e->buffy+1 < owl_editwin_get_numlines(e)) {
    859         e->buffx=0;
    860         e->buffy++;
    861         owl_editwin_move_to_nextword(e);
    862       }
    863     }
    864   }
    865 }
    866 
    867 /* go backwards to the last non-space character
    868  */
    869 void owl_editwin_move_to_previousword(owl_editwin *e)
    870 {
    871   int i;
    872   gunichar c;
    873   char *ptr1, *ptr2;
    874 
    875   /* are we already at the beginning of the word? */
    876   c = _owl_editwin_get_char_at_xy(e);
    877   i = _owl_editwin_get_index_from_xy(e);
    878   ptr1 = e->buff + i;
    879   if (*ptr1 != ' ' && *ptr1 != '\n' && *ptr1 != '\0' ) {
    880     ptr1 = g_utf8_find_prev_char(e->buff, ptr1);
    881     c = g_utf8_get_char(ptr1);
    882     if (c == ' ' || c == '\n') {
    883       owl_editwin_key_left(e);     
    884     }
    885   }
    886 
    887   /* are we starting on a space character? */
    888   i = _owl_editwin_get_index_from_xy(e);
    889   while (i > e->lock && (e->buff[i] == ' ' || e->buff[i] == '\n' || e->buff[i] == '\0')) {
    890     /* find the first non-space */
    891     owl_editwin_key_left(e);     
    892     i = _owl_editwin_get_index_from_xy(e);
    893   }
    894 
    895   /* find the last non-space */
    896   ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
    897   while (ptr1 >= e->buff + e->lock) {
    898     ptr2 = g_utf8_find_prev_char(e->buff, ptr1);
    899     if (!ptr2) break;
    900    
    901     c = g_utf8_get_char(ptr2);
    902     if (c == ' ' || c == '\n'){
    903       break;
    904     }
    905     owl_editwin_key_left(e);
    906     ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
    907   }
    908 }
    909 
    910 
    911 void owl_editwin_delete_nextword(owl_editwin *e)
    912 {
    913   char *ptr1, *start;
    914   gunichar c;
    915 
    916   if (e->bufflen==0) return;
    917 
    918   start = ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
    919   /* if we start out on a space character then jump past all the
    920      spaces up first */
    921   while (*ptr1 == ' ' || *ptr1 == '\n') {
    922     ++ptr1;
    923   }
    924 
    925   /* then jump past the next word */
    926  
    927   while (ptr1 && ptr1 - e->buff < e->bufflen) {
    928     c = g_utf8_get_char(ptr1);
    929     if (c == ' ' || c == '\n' || c == '\0') break;
    930     ptr1 = g_utf8_find_next_char(ptr1, NULL);
    931   }
    932 
    933   if (ptr1) { /* We broke on a space, */
    934     ptr1 = g_utf8_find_next_char(ptr1, NULL);
    935     if (ptr1) { /* and there's a character after it, */
    936       /* nuke everything back to our starting point. */
    937       _owl_editwin_remove_bytes(e, ptr1 - start);
    938       return;
    939     }
    940   }
    941  
    942   /* If we get here, we ran out of string, drop what's left. */
    943   *start = '\0';
    944   e->bufflen = start - e->buff;
    945 }
    946 
    947 void owl_editwin_delete_previousword(owl_editwin *e)
    948 {
    949   /* go backwards to the last non-space character, then delete chars */
    950   int startpos, endpos;
    951 
    952   startpos = _owl_editwin_get_index_from_xy(e);
    953   owl_editwin_move_to_previousword(e);
    954   endpos = _owl_editwin_get_index_from_xy(e);
    955   _owl_editwin_remove_bytes(e, startpos-endpos);
    956 }
    957 
    958 void owl_editwin_delete_to_endofline(owl_editwin *e)
    959 {
    960   int i;
    961 
    962   if (owl_editwin_get_numchars_on_line(e, e->buffy) > e->buffx) {
    963     /* normal line */
    964     i=_owl_editwin_get_index_from_xy(e);
    965     while(i < e->bufflen) {
    966       if (e->buff[i]!='\n') {
    967         owl_editwin_delete_char(e);
    968       } else if ((e->buff[i]=='\n') && (i==e->bufflen-1)) {
    969         owl_editwin_delete_char(e);
    970       } else {
    971         return;
    972       }
    973     }
    974   } else if (e->buffy+1 < owl_editwin_get_numlines(e)) {
    975     /* line with cursor at the end but not on very last line */
    976     owl_editwin_key_right(e);
    977     owl_editwin_backspace(e);
    978   }
    979 }
    980 
    981 void owl_editwin_move_to_line_end(owl_editwin *e)
    982 {
    983   e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    984 }
    985 
    986 void owl_editwin_move_to_line_start(owl_editwin *e)
    987 {
    988   e->buffx=0;
    989   owl_editwin_adjust_for_locktext(e);
    990 }
    991 
    992 void owl_editwin_move_to_end(owl_editwin *e)
    993 {
    994   /* go to last char */
    995   e->buffy=owl_editwin_get_numlines(e)-1;
    996   e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    997   owl_editwin_key_right(e);
    998 
    999   /* do we need to scroll? */
    1000   /*
    1001   if (e->buffy-e->topline > e->winlines) {
    1002     e->topline+=e->winlines/2;
    1003   }
    1004   */
    1005   owl_editwin_recenter(e);
    1006 }
    1007 
    1008 void owl_editwin_move_to_top(owl_editwin *e)
    1009 {
    1010   _owl_editwin_set_xy_by_index(e, 0);
    1011 
    1012   /* do we need to scroll? */
    1013   e->topline=0;
    1014 
    1015   owl_editwin_adjust_for_locktext(e);
    1016 }
    1017 
    1018 void owl_editwin_fill_paragraph(owl_editwin *e)
    1019 {
    1020   int i, save;
    1021 
    1022   /* save our starting point */
    1023   save=_owl_editwin_get_index_from_xy(e);
    1024 
    1025   /* scan back to the beginning of this paragraph */
    1026   for (i=save; i>=e->lock; i--) {
    1027     if ( (i<=e->lock) ||
    1028          ((e->buff[i]=='\n') && (e->buff[i-1]=='\n'))) {
    1029       _owl_editwin_set_xy_by_index(e, i+1);
    1030       break;
    1031     }
    1032   }
    1033 
    1034   /* main loop */
    1035   while (1) {
    1036     i = _owl_editwin_get_index_from_xy(e);
    1037 
    1038     /* bail if we hit the end of the buffer */
    1039     if (i >= e->bufflen || e->buff[i] == '\0') break;
    1040 
    1041     /* bail if we hit the end of the paragraph */
    1042     if (e->buff[i] == '\n' && e->buff[i+1] == '\n') break;
    1043 
    1044     /* bail if we hit a trailing dot on the buffer */
    1045     if (e->buff[i] == '\n' && e->buff[i+1] == '.'
    1046         && ((i+2) >= e->bufflen || e->buff[i+2] == '\0'))
    1047       break;
    1048 
     1173
     1174    if(ch == '.' || ch == '!' || ch == '?')
     1175      sentence = 1;
     1176    else
     1177      sentence = 0;
     1178  }
     1179
     1180  owl_editwin_backward_paragraph(e);
     1181
     1182  /* Now go through inserting newlines as needed */
     1183  while(e->index < e->mark) {
    10491184    /* if we've travelled too far, linewrap */
    1050     if ((e->buffx) >= e->fillcol) {
    1051       int len = e->bufflen;
     1185    if (owl_editwin_current_column(e) >= e->fillcol)
    10521186      _owl_editwin_linewrap_word(e);
    1053       /* we may have added a character. */
    1054       if (i < save) save += e->bufflen - len;
    1055       _owl_editwin_set_xy_by_index(e, i);
    1056     }
    1057 
    1058     /* did we hit the end of a line too soon? */
    1059     /* asedeno: Here we replace a newline with a space. We may want to
    1060        consider removing the space if the characters to either side
    1061        are CJK ideograms.*/
    1062     i = _owl_editwin_get_index_from_xy(e);
    1063     if (e->buff[i] == '\n' && e->buffx < e->fillcol - 1) {
    1064       /* ********* we need to make sure we don't pull in a word that's too long ***********/
    1065       e->buff[i]=' ';
    1066     }
    1067 
    1068     /* fix spacing */
    1069     i = _owl_editwin_get_index_from_xy(e);
    1070     if (e->buff[i] == ' ' && e->buff[i+1] == ' ') {
    1071       if (e->buff[i-1] == '.' || e->buff[i-1] == '!' || e->buff[i-1] == '?') {
    1072         owl_editwin_key_right(e);
    1073       } else {
    1074         owl_editwin_delete_char(e);
    1075         /* if we did this ahead of the save point, adjust it. Changing
    1076            by one is fine here because we're only removing an ASCII
    1077            space. */
    1078         if (i < save) save--;
    1079       }
    1080     } else {
    1081       owl_editwin_key_right(e);
    1082     }
    1083   }
    1084 
    1085   /* put cursor back at starting point */
    1086   _owl_editwin_set_xy_by_index(e, save);
    1087 
    1088   /* do we need to scroll? */
    1089   if (e->buffy-e->topline < 0) {
    1090     e->topline-=e->winlines/2;
    1091   }
     1187    owl_editwin_point_move(e, 1);
     1188  }
     1189
     1190  oe_restore_excursion(e, &x);
    10921191}
    10931192
     
    10951194int owl_editwin_is_at_end(owl_editwin *e)
    10961195{
    1097   int cur=_owl_editwin_get_index_from_xy(e);
    1098   return (only_whitespace(e->buff+cur));
    1099 }
    1100 
    1101 int owl_editwin_check_dotsend(owl_editwin *e)
    1102 {
    1103   char *p, *p_n, *p_p;
    1104   gunichar c;
     1196  return (only_whitespace(e->buff + e->index));
     1197}
     1198
     1199static int owl_editwin_check_dotsend(owl_editwin *e)
     1200{
     1201  int zdot;
     1202  oe_excursion x;
    11051203
    11061204  if (!e->dotsend) return(0);
    1107 
    1108   p = g_utf8_find_prev_char(e->buff, e->buff + e->bufflen);
    1109   p_n = g_utf8_find_next_char(p, NULL);
    1110   p_p = g_utf8_find_prev_char(e->buff, p);
    1111   c = g_utf8_get_char(p);
    1112   while (p != NULL) {
    1113     if (*p == '.'
    1114         && p_p != NULL && (*p_p == '\n' || *p_p == '\r')
    1115         && p_n != NULL && (*p_n == '\n' || *p_n == '\r')) {
    1116       e->bufflen = p - e->buff;
    1117       e->buff[e->bufflen] = '\0';
    1118       return(1);
    1119     }
    1120     if (c != '\0' && !g_unichar_isspace(c)) return(0);
    1121     p_n = p;
    1122     p = p_p;
    1123     c = g_utf8_get_char(p);
    1124     p_p = g_utf8_find_prev_char(e->buff, p);
    1125   }
    1126   return(0);
     1205  if (e->index != e->bufflen) return (0);
     1206
     1207  oe_save_excursion(e, &x);
     1208
     1209  owl_editwin_point_move(e, -3);
     1210
     1211  zdot = (strcmp(e->buff + e->index, "\n.\n") == 0);
     1212
     1213  oe_restore_excursion(e, &x);
     1214
     1215  return zdot;
    11271216}
    11281217
    11291218void owl_editwin_post_process_char(owl_editwin *e, owl_input j)
    11301219{
    1131   /* check if we need to scroll down */
    1132   if (e->buffy-e->topline >= e->winlines) {
    1133     e->topline+=e->winlines/2;
    1134   }
     1220  /* XXX force a redisplay? */
    11351221  if ((j.ch==13 || j.ch==10) && owl_editwin_check_dotsend(e)) {
    11361222    owl_command_editmulti_done(e);
    11371223    return;
    11381224  }
    1139   owl_editwin_redisplay(e, 0); 
    1140 }
    1141 
    1142 void _owl_editwin_process_char(owl_editwin *e, gunichar j)
    1143 {
    1144   if (!(g_unichar_iscntrl(j) && (j != 10) && (j != 13))) {
    1145     owl_editwin_insert_char(e, j);
    1146   }
    1147 }
    1148 
     1225  owl_editwin_redisplay(e, 0);
     1226}
     1227
     1228static int oe_region_width(owl_editwin *e, int start, int end, int offset)
     1229{
     1230  char *p;
     1231  int width = offset;
     1232 
     1233  for(p = e->buff + start;
     1234      p < e->buff + end;
     1235      p = g_utf8_find_next_char(p, NULL))
     1236    width += oe_char_width(g_utf8_get_char(p), width);
     1237
     1238  return width - offset;
     1239}
     1240
     1241static void oe_insert_char(owl_editwin *e, gunichar c)
     1242{
     1243  oe_excursion x;
     1244  char tmp[7];
     1245  int replaced = -1;
     1246
     1247  if (c == '\r') /* translate CRs to NLs */
     1248    c = '\n';
     1249
     1250  if (!g_unichar_iscntrl(c) || c == '\n' || c== '\t' ) {
     1251    memset(tmp, 0, 7);
     1252
     1253    if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
     1254      return;
     1255    }
     1256
     1257    if (e->cursorx != -1 && e->cursorx + oe_char_width(c, e->cursorx) > e->wrapcol) {
     1258      /* XXX this is actually wrong:
     1259       * + If the line has been been wrapped, we can be past the wrap column but
     1260       *   e->cursorx be much smaller.
     1261       * + If the user went back and inserted a bunch of stuff in the middle of
     1262       *   the line, there may be more than one word past the wrap column.
     1263       */
     1264      oe_save_excursion(e, &x);
     1265
     1266      if (c == ' ' || c == '\t') {
     1267        owl_editwin_point_move(e, -1);
     1268        replaced = -owl_editwin_move_if_in(e, -1, " \t");
     1269        if (!replaced) {
     1270          c = '\n';
     1271          replaced = -1;
     1272        }
     1273      } else {
     1274        while(!owl_editwin_at_beginning_of_line(e)) {
     1275          owl_editwin_point_move(e, -1);
     1276          if (owl_util_can_break_after(owl_editwin_get_char_at_point(e))) {
     1277            replaced = -owl_editwin_move_if_in(e, -1, " \t");
     1278            break;
     1279          }
     1280        }
     1281        if (owl_editwin_at_beginning_of_line(e))
     1282          replaced = -1;
     1283      }
     1284      if (replaced && !owl_editwin_at_beginning_of_line(e))
     1285        owl_editwin_point_move(e, 1);
     1286      if (replaced >= 0) {
     1287        owl_editwin_replace(e, replaced, "\n");
     1288      }
     1289      oe_restore_excursion(e, &x);
     1290    }
     1291
     1292    if (replaced >= 0 && (c == ' ' || c == '\t'))
     1293      return; /* our work here is done */
     1294
     1295    g_unichar_to_utf8(c, tmp);
     1296    owl_editwin_replace(e, 0, tmp);
     1297  }
     1298}
    11491299
    11501300void owl_editwin_process_char(owl_editwin *e, owl_input j)
    11511301{
    1152   if (j.ch == ERR) return;
     1302  if (j.ch == ERR)
     1303    return;
    11531304  /* Ignore ncurses control characters. */
    1154   if (j.ch < 0x100) { 
    1155     _owl_editwin_process_char(e, j.uch);
     1305  if (j.ch < 0x100) {
     1306    oe_insert_char(e, j.uch);
    11561307  }
    11571308}
     
    11621313}
    11631314
    1164 int owl_editwin_get_numchars_on_line(owl_editwin *e, int line)
    1165 {
    1166   int i;
    1167   char *ptr1, *ptr2;
    1168 
    1169   if (e->bufflen==0) return(0);
     1315char *owl_editwin_get_region(owl_editwin *e)
     1316{
     1317  int start, end;
     1318  start = e->index;
     1319  end   = e->mark;
     1320  if(start > end) {
     1321    int tmp = end;
     1322    end = start;
     1323    start = tmp;
     1324  }
     1325
     1326  return oe_chunk(e, start, end);
     1327}
     1328
     1329int owl_editwin_get_echochar(owl_editwin *e)
     1330{
     1331  return e->echochar;
     1332}
     1333
     1334static char *oe_chunk(owl_editwin *e, int start, int end)
     1335{
     1336  char *p;
    11701337 
    1171   /* first go to the yth line */
    1172   ptr1=e->buff;
    1173   for (i=0; i<line; i++) {
    1174     ptr2=strchr(ptr1, '\n');
    1175     if (!ptr2) {
    1176       /* we're already on the last line */
    1177       return(0);
    1178     }
    1179     ptr1=ptr2+1;
    1180   }
    1181 
    1182   /* now count characters */
    1183   i = 0;
    1184   ptr2 = ptr1;
    1185   while (ptr2 - e->buff < e->bufflen
    1186          && *ptr2 != '\n') {
    1187     ++i;
    1188     ptr2 = g_utf8_next_char(ptr2);
    1189   }
    1190   return i;
    1191 }
    1192 
    1193 int owl_editwin_get_numcells_on_line(owl_editwin *e, int line)
    1194 {
    1195   int i;
    1196   char *ptr1, *ptr2;
    1197   gunichar c;
    1198 
    1199   if (e->bufflen==0) return(0);
    1200  
    1201   /* first go to the yth line */
    1202   ptr1=e->buff;
    1203   for (i=0; i<line; i++) {
    1204     ptr2=strchr(ptr1, '\n');
    1205     if (!ptr2) {
    1206       /* we're already on the last line */
    1207       return(0);
    1208     }
    1209     ptr1=ptr2+1;
    1210   }
    1211 
    1212   /* now count cells */
    1213   i = 0;
    1214   ptr2 = ptr1;
    1215   while (ptr2 - e->buff < e->bufflen
    1216          && *ptr2 != '\n') {
    1217     c = g_utf8_get_char(ptr2);
    1218     i += mk_wcwidth(c);
    1219     ptr2 = g_utf8_next_char(ptr2);
    1220   }
    1221   return i;
    1222 }
    1223 
    1224 int owl_editwin_get_numlines(owl_editwin *e)
    1225 {
    1226   return(owl_text_num_lines(e->buff));
    1227 }
    1228 
     1338  p = owl_malloc(end - start + 1);
     1339  memcpy(p, e->buff + start, end - start);
     1340  p[end - start] = 0;
     1341
     1342  return p;
     1343}
     1344
     1345/*
     1346 * The only guarantee made about these values is that comparisons
     1347 * between them, as well as comparison between multiple calls to these
     1348 * functions without modifying the editwin in-between, are meaningful.
     1349 */
     1350
     1351int owl_editwin_get_point(owl_editwin *e)
     1352{
     1353  return e->index;
     1354}
     1355
     1356int owl_editwin_get_mark(owl_editwin *e)
     1357{
     1358  return e->mark;
     1359}
     1360
     1361
     1362
     1363/*
     1364 * Local Variables:
     1365 * mode:C
     1366 * c-basic-offset:2
     1367 * End:
     1368 */
  • functions.c

    r8daf504 re6d989f  
    224224
    225225/* Create an outgoing zephyr message and return a pointer to it.  Does
    226  * not put it on the global queue, use owl_function_add_message() for
     226 * not put it on the global queue, use owl_global_messagequeue_addmsg() for
    227227 * that.
    228228 */
     
    246246 * message or NULL if we're not logged into AIM (and thus unable to
    247247 * create the message).  Does not put it on the global queue.  Use
    248  * owl_function_add_message() for that .
     248 * owl_global_messagequeue_addmsg() for that .
    249249 */
    250250owl_message *owl_function_make_outgoing_aim(char *body, char *to)
     
    267267/* Create an outgoing loopback message and return a pointer to it.
    268268 * Does not append it to the global queue, use
    269  * owl_function_add_message() for that.
     269 * owl_global_messagequeue_addmsg() for that.
    270270 */
    271271owl_message *owl_function_make_outgoing_loopback(char *body)
     
    25702570 *
    25712571 * if the curmsg is a personal zephyr return a filter name
    2572  *    to the zephyr converstaion with that user.
     2572 *    to the zephyr conversation with that user.
    25732573 * If the curmsg is a zephyr class message, instance foo, recip *,
    25742574 *    return a filter name to the class, inst.
     
    31083108      ret=owl_zephyr_get_anyone_list(&anyone, filename);
    31093109      if (ret) {
    3110         owl_fmtext_append_normal(&fm, "  Error opening file for zephyr buddies.\n");
     3110        if (errno == ENOENT) {
     3111          owl_fmtext_append_normal(&fm, " You have not added any zephyr buddies.  Use the\n");
     3112          owl_fmtext_append_normal(&fm, " command ':addbuddy zephyr ");
     3113          owl_fmtext_append_bold(  &fm, "<username>");
     3114          owl_fmtext_append_normal(&fm, "'.\n");
     3115        } else {
     3116          owl_fmtext_append_normal(&fm, " Could not read zephyr buddies from the .anyone file.\n");
     3117        }
    31113118      } else {
    31123119        j=owl_list_get_size(&anyone);
     
    35943601  _owl_function_mark_message(m);
    35953602  owl_global_set_curmsg(&g, owl_view_get_nearest_to_msgid(v, marked_id));
     3603  owl_function_calculate_topmsg(OWL_DIRECTION_NONE);
    35963604  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
    35973605  owl_global_set_direction_downwards(&g);
  • global.c

    rbd783db ra556caa  
    4747  g->rightshift=0;
    4848
    49   owl_editwin_init(&(g->tw), NULL, owl_global_get_typwin_lines(g), g->cols, OWL_EDITWIN_STYLE_ONELINE, NULL);
     49  g->tw = owl_editwin_allocate();
     50  owl_editwin_init(g->tw, NULL, owl_global_get_typwin_lines(g), g->cols, OWL_EDITWIN_STYLE_ONELINE, NULL);
    5051
    5152  owl_keyhandler_init(&g->kh);
     
    147148  g->typwin=newwin(typwin_lines, cols, g->recwinlines+2, 0);
    148149
    149   owl_editwin_set_curswin(&(g->tw), g->typwin, typwin_lines, g->cols);
     150  owl_editwin_set_curswin(g->tw, g->typwin, typwin_lines, g->cols);
    150151
    151152  idlok(g->typwin, FALSE);
     
    261262
    262263owl_editwin *owl_global_get_typwin(owl_global *g) {
    263   return(&(g->tw));
     264  return(g->tw);
    264265}
    265266
     
    478479  owl_mainwin_redisplay(&(g->mw));
    479480  sepbar(NULL);
    480   owl_editwin_redisplay(&(g->tw), 0);
     481  owl_editwin_redisplay(g->tw, 0);
    481482  owl_function_full_redisplay(&g);
    482483
  • help.c

    r799b60e re6d989f  
    5858     "\n"
    5959     "    M-n           View zephyrs in selected conversation\n"
    60      "    M-N           View zephyrs in selected converstaion of instance\n"
     60     "    M-N           View zephyrs in selected conversation of instance\n"
    6161     "    M-p           View only personal zephyrs\n"
    6262     "    V             Change to back to home view ('all' by default)\n"
  • keys.c

    r4f0a2ee r2fc8397  
    4545  BIND_CMD("M-O 3 C",     "edit:move-next-word", "");
    4646  BIND_CMD("M-RIGHT",     "edit:move-next-word", "");
     47  BIND_CMD("M-[ 1 ; 3 D", "edit:move-next-word", "");
    4748  BIND_CMD("M-b",         "edit:move-prev-word", "");
    4849  BIND_CMD("M-O 3 D",     "edit:move-prev-word", "");
    4950  BIND_CMD("M-LEFT",      "edit:move-prev-word", "");
     51  BIND_CMD("M-[ 1 ; 3 C", "edit:move-next-word", "");
    5052
    5153  BIND_CMD("LEFT",        "edit:move-left", "");
     
    8284  BIND_CMD("M-q",         "edit:fill-paragraph", "");
    8385
     86  BIND_CMD("C-@",         "edit:set-mark", "");
     87  BIND_CMD("C-x C-x",     "edit:exchange-point-and-mark", "");
     88
     89  BIND_CMD("M-w",         "edit:copy-region-as-kill", "");
     90  BIND_CMD("C-w",         "edit:kill-region", "");
     91  BIND_CMD("C-y",         "edit:yank", "");
     92
    8493  BIND_CMD("C-l",         "( edit:recenter ; redisplay )", "");
    8594
     
    100109  BIND_CMD("M-[ B",   "editmulti:move-down-line", "");
    101110  BIND_CMD("C-n",     "editmulti:move-down-line", "");
     111
     112  BIND_CMD("M-}",     "editmulti:forward-paragraph", "");
     113  BIND_CMD("M-{",     "editmulti:backward-paragraph", "");
    102114
    103115  /* This would be nice, but interferes with C-c to cancel */
  • owl.c

    r1be5823 r301c975  
    145145  /* turn ISTRIP off */
    146146  tcgetattr(0, &tio);
    147   tio.c_iflag &= ~ISTRIP;
     147  tio.c_iflag &= ~(ISTRIP|IEXTEN);
    148148  tio.c_cc[VQUIT] = 0;
    149149  tcsetattr(0, TCSAFLUSH, &tio);
  • perl/lib/BarnOwl.pm

    rfd8dfe7 r22b54a7  
    1818use BarnOwl::Style;
    1919use BarnOwl::Timer;
     20use BarnOwl::Editwin;
    2021
    2122=head1 NAME
     
    316317}
    317318
     319=head2 Modify filters by appending text
     320
     321=cut
     322
     323BarnOwl::new_command("filterappend",
     324    sub { filter_append_helper('appending', '', @_); },
     325    {
     326        summary => "append '<text>' to filter",
     327        usage => "filterappend <filter> <text>",
     328    });
     329
     330BarnOwl::new_command("filterand",
     331    sub { filter_append_helper('and-ing', 'and', @_); },
     332    {
     333        summary => "append 'and <text>' to filter",
     334        usage => "filterand <filter> <text>",
     335    });
     336
     337BarnOwl::new_command("filteror",
     338    sub { filter_append_helper('or-ing', 'or', @_); },
     339    {
     340        summary => "append 'or <text>' to filter",
     341        usage => "filteror <filter> <text>",
     342    });
     343
     344=head3 filter_append_helper ACTION SEP FUNC FILTER APPEND_TEXT
     345
     346Helper to append to filters.
     347
     348=cut
     349
     350sub filter_append_helper
     351{
     352    my $action = shift;
     353    my $sep = shift;
     354    my $func = shift;
     355    my $filter = shift;
     356    my @append = @_;
     357    my $oldfilter = BarnOwl::getfilter($filter);
     358    chomp $oldfilter;
     359    my $newfilter = join(' ', $oldfilter, $sep, @_);
     360    my $msgtext = "To filter '$filter' $action\n'".join(' ', @append)."' to get\n'$newfilter'";
     361    if (BarnOwl::getvar('showfilterchange') eq 'on') {
     362        BarnOwl::admin_message("Filter", $msgtext);
     363    }
     364    BarnOwl::filter($filter, $newfilter);
     365    return;
     366}
     367BarnOwl::new_variable_bool("showfilterchange",
     368                           { default => 1,
     369                             summary => 'Show modifications to filters by filterappend and friends.'});
    318370
    3193711;
  • perl/lib/BarnOwl/Message.pm

    rfd8dfe7 rd1ae4a4  
    2222sub direction   { return shift->{"direction"}; }
    2323sub time        { return shift->{"time"}; }
     24sub unix_time   { return shift->{"unix_time"}; }
    2425sub id          { return shift->{"id"}; }
    2526sub body        { return shift->{"body"}; }
  • perl/lib/BarnOwl/Message/Zephyr.pm

    rbc8275e r30e7ffd  
    179179
    180180    my $cmd;
    181     if(lc $self->opcode eq 'crypt') {
     181    if(lc $self->opcode eq 'crypt' and ( not $sender or $self->is_private)) {
     182        # Responses to zcrypted messages should be zcrypted, so long as we
     183        # aren't switching to personals
    182184        $cmd = 'zcrypt';
    183185    } else {
  • perl/lib/BarnOwl/Style/Default.pm

    ree183be r5550eb0  
    33
    44package BarnOwl::Style::Default;
     5use POSIX qw(strftime);
     6
    57################################################################################
    68# Branching point for various formatting functions in this style.
     
    4042    my $self = shift;
    4143    my $m = shift;
    42     my ($time) = $m->time =~ /(\d\d:\d\d)/;
    43     return $time;
     44    return strftime('%H:%M', localtime($m->unix_time));
    4445}
    4546
  • perl/modules/IRC/lib/BarnOwl/Module/IRC.pm

    r1b62a55 r48f7d12  
    6060    register_commands();
    6161    register_handlers();
    62     BarnOwl::filter('irc type ^IRC$');
     62    BarnOwl::filter('irc type ^IRC$ or ( type ^admin$ and adminheader ^IRC$ )');
    6363}
    6464
     
    375375    $conn->conn->disconnect;
    376376    delete $ircnets{$conn->alias};
     377    return;
    377378}
    378379
     
    387388        BarnOwl::start_edit_win("/msg -a " . $conn->alias . " $to", sub {process_msg($conn, $to, @_)});
    388389    }
     390    return;
    389391}
    390392
     
    415417       );
    416418    BarnOwl::queue_message($msg);
     419    return;
    417420}
    418421
     
    423426    $target ||= shift;
    424427    $conn->conn->mode($target, @_);
     428    return;
    425429}
    426430
     
    432436    push @{$channels{$chan}}, $conn;
    433437    $conn->conn->join($chan, @_);
     438    return;
    434439}
    435440
     
    440445    $channels{$chan} = [grep {$_ ne $conn} @{$channels{$chan} || []}];
    441446    $conn->conn->part($chan);
     447    return;
    442448}
    443449
     
    447453    my $nick = shift or die("Usage: $cmd <new nick>\n");
    448454    $conn->conn->nick($nick);
     455    return;
    449456}
    450457
     
    455462    $conn->names_tmp([]);
    456463    $conn->conn->names($chan);
     464    return;
    457465}
    458466
     
    462470    my $who = shift || die("Usage: $cmd <user>\n");
    463471    $conn->conn->whois($who);
     472    return;
    464473}
    465474
     
    468477    my $conn = shift;
    469478    $conn->conn->motd;
     479    return;
    470480}
    471481
     
    477487    }
    478488    BarnOwl::popless_ztext($message);
     489    return;
    479490}
    480491
     
    485496    BarnOwl::error("WHO $cmd $conn $who");
    486497    $conn->conn->who($who);
     498    return;
    487499}
    488500
     
    492504    my $type = shift || die("Usage: $cmd <chiklmouy> [server] \n");
    493505    $conn->conn->stats($type, @_);
     506    return;
    494507}
    495508
     
    499512    my $chan = shift;
    500513    $conn->conn->topic($chan, @_ ? join(" ", @_) : undef);
     514    return;
    501515}
    502516
     
    505519    my $conn = shift;
    506520    $conn->conn->sl(join(" ", @_));
     521    return;
    507522}
    508523
  • perl/modules/IRC/lib/BarnOwl/Module/IRC/Connection.pm

    r32620ac r7c83a32  
    273273        $self->whois_tmp
    274274    );
    275     $self->whois_tmp([]);
     275    $self->whois_tmp('');
    276276}
    277277
  • perlconfig.c

    rfd8dfe7 ra556caa  
    8787  }
    8888  (void)hv_store(h, "time", strlen("time"), newSVpv(owl_message_get_timestr(m),0),0);
     89  (void)hv_store(h, "unix_time", strlen("unix_time"), newSViv(m->time), 0);
    8990  (void)hv_store(h, "id", strlen("id"), newSViv(owl_message_get_id(m)),0);
    9091  (void)hv_store(h, "deleted", strlen("deleted"), newSViv(owl_message_is_delete(m)),0);
     
    481482void owl_perlconfig_edit_callback(owl_editwin *e)
    482483{
    483   SV *cb = (SV*)(e->cbdata);
     484  SV *cb = (SV*)owl_editwin_get_cbdata(e);
    484485  SV *text;
    485486  dSP;
     
    508509
    509510  SvREFCNT_dec(cb);
    510   e->cbdata = NULL;
     511  owl_editwin_set_cbdata(e, NULL);
    511512}
    512513
  • perlglue.xs

    rfd8dfe7 rc6ecf5c  
    429429                owl_function_debugmsg("Freeing timer %p", t);
    430430                                owl_select_remove_timer(t);
     431
     432MODULE = BarnOwl                PACKAGE = BarnOwl::Editwin
     433
     434int
     435replace(count, string)
     436        int count;
     437        char *string;
     438        CODE:
     439                RETVAL = owl_editwin_replace(owl_global_get_typwin(&g), count, string);
     440        OUTPUT:
     441                RETVAL
     442
     443int
     444point_move(delta)
     445        int delta;
     446        CODE:
     447                RETVAL = owl_editwin_point_move(owl_global_get_typwin(&g), delta);
     448        OUTPUT:
     449                RETVAL
     450
     451int
     452replace_region(string)
     453        char *string;
     454        CODE:
     455                RETVAL = owl_editwin_replace_region(owl_global_get_typwin(&g), string);
     456        OUTPUT:
     457                RETVAL
     458
     459char *
     460get_region()
     461        PREINIT:
     462                char *region;
     463        CODE:
     464                region = owl_editwin_get_region(owl_global_get_typwin(&g));
     465                RETVAL = region;
     466        OUTPUT:
     467                RETVAL
     468        CLEANUP:
     469                owl_free(region);
     470
     471SV *
     472save_excursion(sub)
     473        SV *sub;
     474        PROTOTYPE: &
     475        PREINIT:
     476                int count;
     477                owl_editwin_excursion *x;
     478        CODE:
     479        {
     480                x = owl_editwin_begin_excursion(owl_global_get_typwin(&g));
     481                count = call_sv(sub, G_SCALAR|G_EVAL|G_NOARGS);
     482                owl_editwin_end_excursion(owl_global_get_typwin(&g), x);
     483
     484                if(SvTRUE(ERRSV)) {
     485                        croak(NULL);
     486                }
     487
     488                SPAGAIN;
     489                if(count == 1)
     490                        RETVAL = SvREFCNT_inc(POPs);
     491                else
     492                        XSRETURN_UNDEF;
     493
     494        }
     495        OUTPUT:
     496                RETVAL
     497
     498int
     499current_column()
     500        CODE:
     501                RETVAL = owl_editwin_current_column(owl_global_get_typwin(&g));
     502        OUTPUT:
     503                RETVAL
     504
     505int
     506point()
     507        CODE:
     508                RETVAL = owl_editwin_get_point(owl_global_get_typwin(&g));
     509        OUTPUT:
     510                RETVAL
     511
     512int
     513mark()
     514        CODE:
     515                RETVAL = owl_editwin_get_mark(owl_global_get_typwin(&g));
     516        OUTPUT:
     517                RETVAL
  • tester.c

    reab5aa1 r3e8ff1e  
    77owl_global g;
    88
    9 #define OWL_UTIL_NTESTS  6
     9#define OWL_UTIL_NTESTS  9
    1010#define OWL_DICT_NTESTS  19
    1111#define OWL_OBARRAY_NTESTS  6
  • text.c

    rf34dd65 r3e8ff1e  
    125125
    126126  return(out2);
     127}
     128
     129#define OWL_TAB_WIDTH 8
     130
     131/* Caller must free return */
     132char *owl_text_expand_tabs(char *in)
     133{
     134  int ntabs = 0;
     135  char *p = in;
     136  char *ret, *out;
     137  int col;
     138
     139  while(*p) {
     140    if (*(p++) == '\t') ntabs++;
     141  }
     142
     143  ret = owl_malloc(strlen(in) + 1 + OWL_TAB_WIDTH * ntabs);
     144
     145  p = in;
     146  out = ret;
     147
     148  col = 0;
     149  while(*p) {
     150    switch(*p) {
     151    case '\t':
     152      do {*(out++) = ' '; col++; } while (col % OWL_TAB_WIDTH);
     153      break;
     154    case '\n':
     155      col = -1;
     156    default:
     157      col++;
     158      *(out++) = *p;
     159    }
     160    p++;
     161  }
     162
     163  *out = 0;
     164
     165  return ret;
    127166}
    128167
  • util.c

    r7bf51d5 r3e8ff1e  
    789789              !strcmp("meep", skiptokens("foo 'bar quux' meep", 2)));
    790790
     791  FAIL_UNLESS("expand_tabs 1",
     792              !strcmp("        hi", owl_text_expand_tabs("\thi")));
     793
     794  FAIL_UNLESS("expand_tabs 2",
     795              !strcmp("        hi\nword    tab", owl_text_expand_tabs("\thi\nword\ttab")));
     796
     797  FAIL_UNLESS("expand_tabs 3",
     798              !strcmp("                2 tabs", owl_text_expand_tabs("\t\t2 tabs")));
     799
    791800  /* if (numfailed) printf("*** WARNING: failures encountered with owl_util\n"); */
    792801  printf("# END testing owl_util (%d failures)\n", numfailed);
  • zwrite.c

    r3ef779b ra52d13a  
    99int owl_zwrite_create_from_line(owl_zwrite *z, char *line)
    1010{
    11   int argc, badargs, myargc;
     11  int argc, badargs, myargc, i, len;
    1212  char **argv, **myargv;
     13  char *msg = NULL;
    1314
    1415  badargs=0;
    1516 
    16   /* start with null entires */
     17  /* start with null entries */
    1718  z->realm=NULL;
    1819  z->class=NULL;
     
    8283        break;
    8384      }
    84       /* we must already have users or a class or an instance*/
     85      /* we must already have users or a class or an instance */
    8586      if (owl_list_get_size(&(z->recips))<1 && (!z->class) && (!z->inst)) {
    8687        badargs=1;
     
    9192      myargv++;
    9293      myargc--;
    93       z->message = owl_strdup("");
     94      len = 0;
     95      for (i=0;i<myargc;i++) {
     96        len += strlen(myargv[i-1]) + 1;
     97      }
     98      msg = owl_malloc(len);
     99      msg[0] = '\0';
    94100      while (myargc) {
    95         z->message=owl_realloc(z->message, strlen(z->message)+strlen(myargv[0])+5);
    96         strcat(z->message, myargv[0]);
    97         strcat(z->message, " ");
    98         myargc--;
    99         myargv++;
    100       }
    101       z->message[strlen(z->message)-1]='\0'; /* remove last space */
     101        strcat(msg, myargv[0]);
     102        strcat(msg, " ");
     103        myargc--;
     104        myargv++;
     105      }
     106      msg[strlen(msg)-1] = '\0';
    102107      break;
    103108    } else if (!strcmp(myargv[0], "-C")) {
     
    136141  if (z->opcode==NULL) z->opcode=owl_strdup("");
    137142  /* z->message is allowed to stay NULL */
    138  
     143
     144  if(msg) {
     145    owl_zwrite_set_message(z, msg);
     146    owl_free(msg);
     147  }
     148
    139149  return(0);
    140150}
     
    222232  int i, j;
    223233  char *toline = NULL;
    224   char *tmp = NULL;
     234  char *tmp = NULL, *tmp2;
    225235
    226236  if (z->message) owl_free(z->message);
     
    240250    }
    241251    tmp = owl_validate_utf8(msg);
    242     z->message=owl_sprintf("%s\n%s", toline, tmp);
     252    tmp2 = owl_text_expand_tabs(tmp);
     253    z->message=owl_sprintf("%s\n%s", toline, tmp2);
    243254    owl_free(toline);
     255    owl_free(tmp);
     256    owl_free(tmp2);
    244257  } else {
    245     z->message=owl_validate_utf8(msg);
    246   }
    247   if (tmp) owl_free(tmp);
     258    tmp=owl_validate_utf8(msg);
     259    z->message=owl_text_expand_tabs(tmp);
     260    owl_free(tmp);
     261  }
    248262}
    249263
Note: See TracChangeset for help on using the changeset viewer.