... | ... |
@@ -1679,10 +1679,64 @@ redata_pos2linecol(redata_t *redata, long pos, int *resline, int *rescol) |
1679 | 1679 |
int |
1680 | 1680 |
redata_linecol2pos(redata_t *redata, int line, int colrequest, long *pos, int *coldone) |
1681 | 1681 |
{ |
1682 |
-#warning TODO: XXX Implement this function |
|
1683 |
-#warning TODO: XXX: Add a parameter so this is like reata_line_inccol (colrequest, coldone) -- maybe also linetrequest linedone? (zed doesn''t let you go to the last line doing a Ctrl+q+l to an arbitrarily large number...) |
|
1684 |
-#warning TODO: XXX: The extra parameters are super-handy because the main user of this function is Control+Q+L "Go To Line" and we want to go to nearest pos |
|
1685 |
- return(-1); |
|
1682 |
+ long chunkpos,realstart,newpos,curpos,startpos; |
|
1683 |
+ int startline; |
|
1684 |
+ int nchunk; |
|
1685 |
+ rechunk_t *chunk; |
|
1686 |
+ int i,n; |
|
1687 |
+ char *ptr; |
|
1688 |
+ int len; |
|
1689 |
+ int done; |
|
1690 |
+ if(redata==NULL || line<0 || colrequest<0) |
|
1691 |
+ return(-1); |
|
1692 |
+ /* find line */ |
|
1693 |
+ for(nchunk=0,chunkpos=0,startline=0 |
|
1694 |
+ ;nchunk<redata->sizechunks |
|
1695 |
+ ;chunkpos+=(chunk!=NULL)?chunk->useddata:0 |
|
1696 |
+ ,startline+=(chunk!=NULL)?chunk->whatin.nlcount:0,nchunk++) { |
|
1697 |
+ if((chunk=redata->chunks[nchunk])==NULL) |
|
1698 |
+ continue; |
|
1699 |
+ if(!(chunk->whatin_fresh)) |
|
1700 |
+ redata_whatin_refresh(redata,nchunk); |
|
1701 |
+ if(line>=startline && line<=(startline+chunk->whatin.nlcount)) |
|
1702 |
+ break; |
|
1703 |
+ } |
|
1704 |
+ if(nchunk>=redata->sizechunks) |
|
1705 |
+ return(-1); /* line not found */ |
|
1706 |
+ for(i=0;line!=startline && i<chunk->useddata;i++) { |
|
1707 |
+ if(chunk->data[i]=='\n') |
|
1708 |
+ startline++; |
|
1709 |
+ } |
|
1710 |
+ if(i>chunk->useddata) |
|
1711 |
+ return(-1); /* line not found */ |
|
1712 |
+ realstart=chunkpos+i; |
|
1713 |
+ /* find col */ |
|
1714 |
+ for(n=0,curpos=realstart;n<colrequest;) { |
|
1715 |
+ if(redata_line_rawinfo(redata,curpos,&startpos,&ptr,&len,NULL)==-1 || len==0) |
|
1716 |
+ return(-1); /* couldn't get current line data */ |
|
1717 |
+ done=0; |
|
1718 |
+ for(i=0;colrequest>0 && i<len && n<=colrequest;i++) { |
|
1719 |
+ if(redata_generic_utf8isstartbyte(ptr[i])) { |
|
1720 |
+ if(n==colrequest) { |
|
1721 |
+ done=1; |
|
1722 |
+ break; |
|
1723 |
+ } |
|
1724 |
+ n++; |
|
1725 |
+ } |
|
1726 |
+ if(ptr[i]=='\n') { |
|
1727 |
+ done=1; |
|
1728 |
+ break; |
|
1729 |
+ } |
|
1730 |
+ } |
|
1731 |
+ curpos=startpos+i; |
|
1732 |
+ if(done) |
|
1733 |
+ break; |
|
1734 |
+ } |
|
1735 |
+ if(coldone!=NULL) |
|
1736 |
+ *coldone=n; |
|
1737 |
+ if(pos!=NULL) |
|
1738 |
+ *pos=curpos; |
|
1739 |
+ return(0); |
|
1686 | 1740 |
} |
1687 | 1741 |
|
1688 | 1742 |
static char * |
... | ... |
@@ -148,7 +148,7 @@ int redata_generic_utf8len(char *ptr, int size); |
148 | 148 |
char *redata_generic_utf8col(char *ptr, int size, int col); |
149 | 149 |
/* returns the len in bytes of the character starting at ptr (zero on error)*/ |
150 | 150 |
int redata_generic_utf8charlen(char *ptr, int maxsize); |
151 |
-/* returns true if it's the forst byte of an UTF char */ |
|
151 |
+/* returns true if it's the first byte of an UTF char */ |
|
152 | 152 |
int redata_generic_utf8isstartbyte(int candidate); |
153 | 153 |
|
154 | 154 |
|
... | ... |
@@ -487,8 +487,9 @@ re_processcommand(re_t *re) |
487 | 487 |
if(strcmp(re->command,COMMAND_GOTOLINE)==0) { |
488 | 488 |
int line; |
489 | 489 |
long pos; |
490 |
- line=atoi(re->commandbuf); |
|
491 |
- if(redata_linecol2pos(re->data,line,0,&pos,NULL)==-1) { |
|
490 |
+ line=atoi(re->commandbuf)-1; |
|
491 |
+ line=(line<0)?0:line; |
|
492 |
+ if(redata_linecol2pos(re->data,line,re->curcol,&pos,NULL)==-1) { |
|
492 | 493 |
re->command=COMMAND_WARNING; |
493 | 494 |
snprintf(re->commandbuf,sizeof(re->commandbuf),"Unknown line"); |
494 | 495 |
re->commandbuf[sizeof(re->commandbuf)-1]='\0'; |
... | ... |
@@ -496,13 +497,9 @@ re_processcommand(re_t *re) |
496 | 497 |
return(-1); |
497 | 498 |
} |
498 | 499 |
re->cursorpos=pos; |
499 |
- re->curcol=0; |
|
500 | 500 |
re->curline=line; |
501 |
- re->origincol=0; |
|
502 |
- if((re->originline+re->maxrow)<line) |
|
503 |
- re->originline=line-re->maxrow; |
|
504 |
- if(line<re->originline) |
|
505 |
- re->originline=line; |
|
501 |
+ /* position the line in the center of viewport */ |
|
502 |
+ re->originline=line-(re->maxrow/2); |
|
506 | 503 |
re->headerdirty=1; |
507 | 504 |
re->contentsdirty=1; |
508 | 505 |
} |
... | ... |
@@ -669,7 +666,8 @@ re_drawheader_editing(re_t *re) |
669 | 666 |
if(redata_pos2linecol(re->data,re->cursorpos,&line,&col)==-1) |
670 | 667 |
line=col=-1; |
671 | 668 |
reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_STATUSBG); |
672 |
- reui_printf(re->ui,0,0,COLOR_STATUSFG,"File: %s Line:%i (%i) Col:%i (%i) Pos:%li",re->filename,re->curline,line,re->curcol,col,re->cursorpos); |
|
669 |
+ /* for the user, lines start at 0 (internally they start at 0) */ |
|
670 |
+ reui_printf(re->ui,0,0,COLOR_STATUSFG,"File: %s Line:%i (%i) Col:%i (%i) Pos:%li",re->filename,re->curline+1,line+1,re->curcol+1,col+1,re->cursorpos); |
|
673 | 671 |
re->headerdirty=0; |
674 | 672 |
re->ui->rendererdirty=1; |
675 | 673 |
return(0); |