📄 ublock.c
字号:
/* * Highlighted block functions * Copyright * (C) 1992 Joseph H. Allen * * This file is part of JOE (Joe's Own Editor) */#include "types.h"#ifdef HAVE_SYS_WAIT_H#include <sys/wait.h>#endifint nowmarking;/* Global options */int square = 0; /* Set for rectangle mode */int lightoff = 0; /* Set if highlighting should turn off after block operations *//* Global variables */P *markb = NULL; /* Beginning and end of block */P *markk = NULL;/* Push markb & markk */typedef struct marksav MARKSAV;struct marksav { LINK(MARKSAV) link; P *markb, *markk;} markstack = { { &markstack, &markstack} };MARKSAV markfree = { {&markfree, &markfree} };int nstack = 0;int upsh(BW *bw){ MARKSAV *m = alitem(&markfree, sizeof(MARKSAV)); m->markb = 0; m->markk = 0; if (markk) pdupown(markk, &m->markk, USTR "upsh"); if (markb) pdupown(markb, &m->markb, USTR "upsh"); enqueb(MARKSAV, link, &markstack, m); ++nstack; return 0;}int upop(BW *bw){ MARKSAV *m = markstack.link.prev; if (m != &markstack) { --nstack; prm(markk); prm(markb); markk = m->markk; if (markk) markk->owner = &markk; markb = m->markb; if (markb) markb->owner = &markb; demote(MARKSAV, link, &markfree, m); if (lightoff) unmark(bw); updall(); return 0; } else return -1;}/* Return true if markb/markk are valid *//* If r is set, swap markb with markk if necessary */int autoswap;int markv(int r){ if (markb && markk && markb->b == markk->b && markk->byte > markb->byte && (!square || markk->xcol > markb->xcol)) { return 1; } else if(autoswap && r && markb && markk && markb->b == markk->b && markb->byte > markk->byte && (!square || markk->xcol < markb->xcol)) { P *p = pdup(markb, USTR "markv"); prm(markb); markb=0; pdupown(markk, &markb, USTR "markv"); prm(markk); markk=0; pdupown(p, &markk, USTR "markv"); prm(p); return 1; } else return 0;}/* Rectangle-mode subroutines *//* B *pextrect(P *org,long height,long left,long right); * Copy a rectangle into a new buffer * * org points to top-left corner of rectangle. * height is number of lines in rectangle. * right is rightmost column of rectangle + 1 */B *pextrect(P *org, long int height, long int right){ P *p = pdup(org, USTR "pextrect"); /* Left part of text to extract */ P *q = pdup(p, USTR "pextrect"); /* After right part of text to extract */ B *tmp = bmk(NULL); /* Buffer to extract to */ P *z = pdup(tmp->eof, USTR "pextrect"); /* Buffer pointer */ while (height--) { pcol(p, org->xcol); pset(q, p); pcolwse(q, right); p_goto_eof(z); binsb(z, bcpy(p, q)); p_goto_eof(z); binsc(z, '\n'); pnextl(p); } prm(p); prm(q); prm(z); return tmp;}/* void pdelrect(P *org,long height,long right); * Delete a rectangle. */void pdelrect(P *org, long int height, long int right){ P *p = pdup(org, USTR "pdelrect"); P *q = pdup(p, USTR "pdelrect"); while (height--) { pcol(p, org->xcol); pset(q, p); pcol(q, right); bdel(p, q); pnextl(p); } prm(p); prm(q);}/* void pclrrect(P *org,long height,long right,int usetabs); * Blank-out a rectangle. */void pclrrect(P *org, long int height, long int right, int usetabs){ P *p = pdup(org, USTR "pclrrect"); P *q = pdup(p, USTR "pclrrect"); while (height--) { long pos; pcol(p, org->xcol); pset(q, p); pcoli(q, right); pos = q->col; bdel(p, q); pfill(p, pos, usetabs); pnextl(p); } prm(p); prm(q);}/* int ptabrect(P *org,long height,long right) * Check if there are any TABs in a rectangle */int ptabrect(P *org, long int height, long int right){ P *p = pdup(org, USTR "ptabrect"); while (height--) { int c; pcol(p, org->xcol); while ((c = pgetc(p)) != NO_MORE_DATA && c != '\n') { if (c == '\t') { prm(p); return '\t'; } else if (piscol(p) > right) break; } if (c != '\n') pnextl(p); } prm(p); return ' ';}/* Insert rectangle */void pinsrect(P *cur, B *tmp, long int width, int usetabs){ P *p = pdup(cur, USTR "pinsrect"); /* We insert at & move this pointer */ P *q = pdup(tmp->bof, USTR "pinsrect"); /* These are for scanning through 'tmp' */ P *r = pdup(q, USTR "pinsrect"); if (width) while (pset(r, q), p_goto_eol(q), (q->line != tmp->eof->line || piscol(q))) { pcol(p, cur->xcol); if (piscol(p) < cur->xcol) pfill(p, cur->xcol, usetabs); binsb(p, bcpy(r, q)); pfwrd(p, q->byte - r->byte); if (piscol(p) < cur->xcol + width) pfill(p, cur->xcol + width, usetabs); if (piseol(p)) pbackws(p); if (!pnextl(p)) { binsc(p, '\n'); pgetc(p); } if (pgetc(q) == NO_MORE_DATA) break; } prm(p); prm(q); prm(r);}/* Block functions *//* Set beginning */int umarkb(BW *bw){ pdupown(bw->cursor, &markb, USTR "umarkb"); markb->xcol = bw->cursor->xcol; updall(); return 0;}int udrop(BW *bw){ prm(markk); if (marking && markb) prm(markb); else umarkb(bw); return 0;}int ubegin_marking(BW *bw){ if (nowmarking) { /* We're marking now... don't stop */ return 0; } else if (markv(0) && bw->cursor->b==markb->b) { /* Try to extend current block */ if (bw->cursor->byte==markb->byte) { pset(markb,markk); prm(markk); markk=0; nowmarking = 1; return 0; } else if(bw->cursor->byte==markk->byte) { prm(markk); markk=0; nowmarking = 1; return 0; } } /* Start marking - no message */ prm(markb); markb=0; prm(markk); markk=0; updall(); nowmarking = 1; return umarkb(bw);}int utoggle_marking(BW *bw){ if (markv(0) && bw->cursor->b==markb->b && bw->cursor->byte>=markb->byte && bw->cursor->byte<=markk->byte) { /* Just clear selection */ prm(markb); markb=0; prm(markk); markk=0; updall(); nowmarking = 0; msgnw(bw->parent, joe_gettext(_("Selection cleared."))); return 0; } else if (markk) { /* Clear selection and start new one */ prm(markb); markb=0; prm(markk); markk=0; updall(); nowmarking = 1; msgnw(bw->parent, joe_gettext(_("Selection started."))); return umarkb(bw); } else if (markb && markb->b==bw->cursor->b) { nowmarking = 0; if (bw->cursor->byte<markb->byte) { pdupown(markb, &markk, USTR "utoggle_marking"); prm(markb); markb=0; pdupown(bw->cursor, &markb, USTR "utoggle_marking"); markb->xcol = bw->cursor->xcol; } else { pdupown(bw->cursor, &markk, USTR "utoggle_marking"); markk->xcol = bw->cursor->xcol; } updall(); /* Because other windows could be changed */ return 0; } else { nowmarking = 1; msgnw(bw->parent, joe_gettext(_("Selection started."))); return umarkb(bw); }}int uselect(BW *bw){ if (!markb) umarkb(bw); return 0;}/* Set end */int umarkk(BW *bw){ pdupown(bw->cursor, &markk, USTR "umarkk"); markk->xcol = bw->cursor->xcol; updall(); return 0;}/* Unset marks */int unmark(BW *bw){ prm(markb); prm(markk); nowmarking = 0; updall(); return 0;}/* Mark line */int umarkl(BW *bw){ p_goto_bol(bw->cursor); umarkb(bw); pnextl(bw->cursor); umarkk(bw); utomarkb(bw); pcol(bw->cursor, bw->cursor->xcol); return 0;}int utomarkb(BW *bw){ if (markb && markb->b == bw->b) { pset(bw->cursor, markb); return 0; } else return -1;}int utomarkk(BW *bw){ if (markk && markk->b == bw->b) { pset(bw->cursor, markk); return 0; } else return -1;}int uswap(BW *bw){ if (markb && markb->b == bw->b) { P *q = pdup(markb, USTR "uswap"); umarkb(bw); pset(bw->cursor, q); prm(q); return 0; } else return -1;}int utomarkbk(BW *bw){ if (markb && markb->b == bw->b && bw->cursor->byte != markb->byte) { pset(bw->cursor, markb); return 0; } else if (markk && markk->b == bw->b && bw->cursor->byte != markk->byte) { pset(bw->cursor, markk); return 0; } else return -1;}/* Delete block */int ublkdel(BW *bw){ if (markv(1)) { if (square) if (bw->o.overtype) { long ocol = markk->xcol; pclrrect(markb, markk->line - markb->line + 1, markk->xcol, ptabrect(markb, markk->line - markb->line + 1, markk->xcol)); pcol(markk, ocol); markk->xcol = ocol; } else pdelrect(markb, markk->line - markb->line + 1, markk->xcol); else bdel(markb, markk); if (lightoff) unmark(bw); } else { msgnw(bw->parent, joe_gettext(_("No block"))); return -1; } return 0;}/* Special delete block function for PICO */int upicokill(BW *bw){ upsh(bw); umarkk(bw); if (markv(1)) { if (square) if (bw->o.overtype) { long ocol = markk->xcol; pclrrect(markb, markk->line - markb->line + 1, markk->xcol, ptabrect(markb, markk->line - markb->line + 1, markk->xcol)); pcol(markk, ocol); markk->xcol = ocol; } else pdelrect(markb, markk->line - markb->line + 1, markk->xcol); else bdel(markb, markk); if (lightoff) unmark(bw); } else udelln(bw); return 0;}/* Move highlighted block */int ublkmove(BW *bw){ if (markv(1)) { if (markb->b!=bw->b && !modify_logic(bw,markb->b)) return -1; if (square) { long height = markk->line - markb->line + 1; long width = markk->xcol - markb->xcol; int usetabs = ptabrect(markb, height, markk->xcol); long ocol = piscol(bw->cursor); B *tmp = pextrect(markb, height, markk->xcol); int update_xcol = (bw->cursor->xcol >= markk->xcol && bw->cursor->line >= markb->line && bw->cursor->line <= markk->line); ublkdel(bw); /* now we can't use markb and markk until we set them again */ /* ublkdel() frees them */ if (bw->o.overtype) { /* If cursor was in block, blkdel moves it to left edge of block, so fix it * back to its original place here */ pcol(bw->cursor, ocol); pfill(bw->cursor, ocol, ' '); pdelrect(bw->cursor, height, piscol(bw->cursor) + width); } else if (update_xcol) /* If cursor was to right of block, xcol was not properly updated */ bw->cursor->xcol -= width; pinsrect(bw->cursor, tmp, width, usetabs); brm(tmp); if (lightoff) unmark(bw); else { umarkb(bw); umarkk(bw); pline(markk, markk->line + height - 1); pcol(markk, markb->xcol + width); markk->xcol = markb->xcol + width; } return 0; } else if (bw->cursor->b != markk->b || bw->cursor->byte > markk->byte || bw->cursor->byte < markb->byte) { long size = markk->byte - markb->byte; binsb(bw->cursor, bcpy(markb, markk)); bdel(markb, markk); if (lightoff) unmark(bw); else { umarkb(bw); umarkk(bw); pfwrd(markk, size); } updall(); return 0; } } msgnw(bw->parent, joe_gettext(_("No block"))); return -1;}/* Duplicate highlighted block */int ublkcpy(BW *bw){ if (markv(1)) { if (square) { long height = markk->line - markb->line + 1; long width = markk->xcol - markb->xcol; int usetabs = ptabrect(markb, height, markk->xcol); B *tmp = pextrect(markb, height, markk->xcol); if (bw->o.overtype) pdelrect(bw->cursor, height, piscol(bw->cursor) + width); pinsrect(bw->cursor, tmp, width, usetabs); brm(tmp); if (lightoff) unmark(bw); else { umarkb(bw); umarkk(bw); pline(markk, markk->line + height - 1); pcol(markk, markb->xcol + width); markk->xcol = markb->xcol + width; } return 0; } else { long size = markk->byte - markb->byte; B *tmp = bcpy(markb, markk); /* Simple overtype for hex mode */ if (bw->o.hex && bw->o.overtype) { P *q = pdup(bw->cursor, USTR "ublkcpy"); if (q->byte + size >= q->b->eof->byte) pset(q, q->b->eof); else pfwrd(q, size); bdel(bw->cursor, q); prm(q); } binsb(bw->cursor, tmp); if (lightoff) unmark(bw); else { umarkb(bw); umarkk(bw); pfwrd(markk, size); } updall(); return 0; } } else { msgnw(bw->parent, joe_gettext(_("No block"))); return -1; }}/* Write highlighted block to a file *//* This is called by ublksave in ufile.c *//*int dowrite(BW *bw, unsigned char *s, void *object, int *notify){ if (notify) *notify = 1; if (markv(1)) { if (square) { int fl; int ret = 0; B *tmp = pextrect(markb, markk->line - markb->line + 1, markk->xcol); if ((fl = bsave(tmp->bof, s, tmp->eof->byte, 0)) != 0) { msgnw(bw->parent, joe_gettext(msgs[-fl])); ret = -1; } brm(tmp); if (lightoff) unmark(bw); vsrm(s); return ret; } else { int fl; int ret = 0; if ((fl = bsave(markb, s, markk->byte - markb->byte, 0)) != 0) { msgnw(bw->parent, joe_gettext(msgs[-fl])); ret = -1; } if (lightoff) unmark(bw); vsrm(s); return ret; } } else { vsrm(s); msgnw(bw->parent, USTR _(_("No block"))); return -1; }}*//* Set highlighted block on a program block */void setindent(BW *bw){ P *p, *q; long indent; if (pisblank(bw->cursor)) return; p = pdup(bw->cursor, USTR "setindent"); q = pdup(p, USTR "setindent"); indent = pisindent(p); do {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -