/************************************************************************ * "Epsilon", "EEL" and "Lugaru" are trademarks of Lugaru Software, Ltd. * * * * Copyright (C) 1985, 1989 Lugaru Software Ltd. All rights reserved. * * * * Limited permission is hereby granted to reproduce and modify this * * copyrighted material provided that the resulting code is used only in * * conjunction with Lugaru products and that this notice is retained in * * any such reproduction or modification. * ************************************************************************/ #include "eel.h" short block_kill_buffers = 10; /* number of block kill buffers */ keytable block_tab; /* block-oriented commands */ char _block_mode_name[] = "Block"; short _start_col, _stop_col; /* columns to operate on */ int _old_yank_pos = -1; /* where yanking happened */ short *_bcolumn_width; /* array of widths for each block kill buffer */ short _num_block_kill; /* # of current block kill buffer */ short _prev_block_kill_buffers; /* value last time */ char _cur_bkill_buf[30]; /* name of kill buffer */ buffer char *_block_old_mode_name; /* save old mode info here */ buffer short *_block_old_mode_keys; buffer char _block_old_over_mode; command block_mode() /* go in or out of block mode */ { iter = 0; if (major_mode == _block_mode_name) { major_mode = _block_old_mode_name; mode_keys = _block_old_mode_keys; over_mode = _block_old_over_mode; } else { _block_old_mode_name = major_mode; _block_old_mode_keys = mode_keys; _block_old_over_mode = over_mode; over_mode = 1; mode_keys = block_tab; major_mode = _block_mode_name; } make_mode(); } command kill_block() on block_tab[CTRL('W')] { /* save and replace w/ spaces */ pick_block(1, 1, 1); } command copy_block() on block_tab[ALT('w')] { pick_block(1, 0, 0); } command delete_block() on block_tab[ALT(CTRL('W'))] { /* remove columns */ pick_block(0, 0, 1); } pick_block(copy, clear, remove) /* copy => push copy of block */ { /* remove => take out block */ int oldpoint, t; /* clear => and put spaces instead */ iter = 0; get_cols(); if (copy) { push_block_kill(); _bcolumn_width[_num_block_kill] = _stop_col - _start_col; } if (point == mark) return; if (point > mark) t = point, point = mark, mark = t; oldpoint = point; for (;;) { /* for each line */ move_to_column(_start_col); t = point; move_to_column(_stop_col); if (copy) xfer(_cur_bkill_buf, t, point); if (remove) delete(t, point); if (clear) insert_to_column(_start_col, _stop_col); if (point >= mark || !nl_forward()) break; if (copy) xfer(_cur_bkill_buf, point - 1, point); } mark = point; /* lower right of block */ point = oldpoint; /* upper left */ move_to_column(_start_col); } get_cols() /* set globals _start_col & _stop_col from point & mark */ { int t; _start_col = current_column(); t = point; point = mark; _stop_col = current_column(); point = t; if (_start_col > _stop_col) t = _start_col, _start_col = _stop_col, _stop_col = t; } command yank_block() on block_tab[CTRL('Y')] { retrieve_block(0); } command yank_pop_block() on block_tab[ALT('y')] { retrieve_block(1); } retrieve_block(withpop) { char *thisbuf = bufname; int startcol = current_column(), stopcol, from, to, t; check_num_kill_buffers(); if (withpop) { if (point != _old_yank_pos) return; pop_block_kill(); /* get the previous kbuf */ undo_op(1), undo_op(1); if (point != _old_yank_pos) { undo_op(0), undo_op(0); error("Must follow yank-block or yank-pop-block"); } } stopcol = startcol + _bcolumn_width[_num_block_kill]; _old_yank_pos = point; bufname = _cur_bkill_buf; if (bufname == thisbuf) return; point = 0; while (point < size()) { from = point; to = nl_forward(); to = point - to; bufname = thisbuf; move_to_column(startcol); if (over_mode) { t = point; move_to_column(stopcol); delete(t, point); } insert_to_column(current_column(), startcol); bufname = _cur_bkill_buf; xfer(thisbuf, from, to); bufname = thisbuf; if (curchar() != '\n') insert_to_column(current_column(), stopcol); mark = point; if (!nl_forward()) insert('\n'); bufname = _cur_bkill_buf; } bufname = thisbuf; point = _old_yank_pos; } check_num_kill_buffers() { int i; if (block_kill_buffers == _prev_block_kill_buffers) return; if (block_kill_buffers < 1) block_kill_buffers = 1; if (_bcolumn_width) free(_bcolumn_width); _bcolumn_width = (short *) malloc(block_kill_buffers * sizeof(short)); for (i = block_kill_buffers; i < _prev_block_kill_buffers; i++) { sprintf(_cur_bkill_buf, "-block-kill-buffer-%d", i); delete_buffer(_cur_bkill_buf); } for (i = 0; i < block_kill_buffers; i++) { sprintf(_cur_bkill_buf, "-block-kill-buffer-%d", i); delete_buffer(_cur_bkill_buf); _bcolumn_width[i] = 0; } _prev_block_kill_buffers = block_kill_buffers; _num_block_kill = 0; } /* Prepare to use another kill buffer. Find the proper one and empty it. */ push_block_kill() { check_num_kill_buffers(); _num_block_kill = (++_num_block_kill) % block_kill_buffers; sprintf(_cur_bkill_buf, "-block-kill-buffer-%d", _num_block_kill); zap(_cur_bkill_buf); /* zap will create if necessary */ } /* make the previous kill buffer current, create if necessary */ pop_block_kill() { if (--_num_block_kill < 0) _num_block_kill += block_kill_buffers; sprintf(_cur_bkill_buf, "-block-kill-buffer-%d", _num_block_kill); create(_cur_bkill_buf); /* no effect if already exists */ }