Version: (using KDE KDE 3.2.1) Installed from: SuSE RPMs OS: Linux i've written a class (some months ago) someone must intergrate it into kdevelop it's a pretty sophisticated feature already. description&howto is included ----------------- [...] // Documentation: // PURPOSE: // implements a global CursorPositionHistory for qeditor (?) etc. // usful when working with large projects/files, and having to do changes in several files // makes finding interesting positions again a lot easier (for example while browsing the code); // also useful during finding out how the code of a certain program is working // also useful when working only with a large single file, as i found out :) // can be more practical than & is not intended as a substitute for bookmarks Special features: - if navigating within a "block" of +/- 7 lines no additional history entry is inserted - if navigating back and then changing the cursor position, the "future" isn't deleted - NavigateLeave deletes the current entry out of the history list (=leave this position), (it also pushes it onto a small stack -> NavigatePop to get it back) ************************** I would have proposed to use the 4 keys Ctrl-Alt-Left/Right/Up/Down, but they seem to be already used for other purposes. ...Ctrl-Alt-Shift-Left/Right are also already used other proposals: Ctrl-Alt-Shift-j/k/l/i Ctrl-Alt-4/5/6/8 (Numpad) etc. ************************** ("light" version with 2 or 3 keys possible) QEditorWidget* NavigateBack(int &line, int &column); // Ctrl-Alt-Left for example QEditorWidget* NavigateLeave(int &line, int &column); // Ctrl-Alt-Up for example QEditorWidget* NavigateForward(int &line, int &column); // Ctrl-Alt-Right for example QEditorWidget* NavigatePop(int &line, int &column); // Ctrl-Alt-Down for example (3key-version: optional) stack: i Pos2 | Pos1 v | *---------------------* UP | DOWN | | history <<<<<-------- current ------------>>>> future LEFT RIGHT KEYPRESSED-EVENT: (PSEUDOCODE) int l,c; QEditorWidget* p; if (p=NavigateBack(l,c)) {setviewactive?(p); setcursor(p,l,c); } ************************** // INTEGRATION: [see source files] .... // perhaps the Application/mainwindow should catch these events and then change to the correct // editor-window+line+column // SideEffects/NECESSARY CHANGES to rest of the Editor-code: // uses QEditorWiget* pointers to identify which of the currently open files is meant // Editor Codes has to inform this Class and use it, and also inform it when a file is closed // Application has to create one object of this class
// CURSHIST.CPP #include "curshist.h" #include <string.h> CGlobalCursorPosHistory::CGlobalCursorPosHistory() { m_hist = new CursHistEntry[GCPH_HISTSZ+2]; // +2 savety (+1 needed) num=0; curr=0; m_stack = new CursHistEntry[GCPH_HSTACK]; num_s=0; } CGlobalCursorPosHistory::~CGlobalCursorPosHistory() { delete[] m_hist; } void CGlobalCursorPosHistory::CursorChanged(QEditorWidget* FileId, int line, int column) { int newidx; int currline=m_hist[curr].LineCol/256; if (line>currline-GCPH_BLOCK && line<currline+GCPH_BLOCK) // replace Entry -- if we are withing same BLOCK newidx = curr; else { // make room for new entry newidx=curr+1; memcpy((void*)&m_hist[newidx+1],(void*)&m_hist[newidx], (num-newidx-1)* sizeof(CursHistEntry)); // remark: might lead to GCPH_HISTSZ+1 entries, but this is ok! num++; // if too much entries, delete either the first or the last if (GCPH_HISTSZ>num) { if (newidx>(3*GCPH_HISTSZ)/5) // 60 % for history, 40 % for future { memcpy((void*)&m_hist[0],(void*)&m_hist[1], GCPH_HISTSZ*sizeof(CursHistEntry)); // delete first entry newidx--; } //else: do nothing // = delete last entry num=GCPH_HISTSZ; } } if (line>0xFFFFFF) line=0xFFFFFF; if (line<0) line=0; if (column>0xFF) column=0xFF; if (column<0) column=0; m_hist[newidx].FileId=FileId; m_hist[newidx].LineCol=256*line+column; } void CGlobalCursorPosHistory::FileClosed(QEditorWidget* FileId) { for (int i=0; i<num; i++) { if (m_hist[i].FileId==FileId) { memcpy((void*)&m_hist[i],(void*)&m_hist[i+1], (num-i-1)*sizeof(CursHistEntry)); num--; if (curr>i) curr--; if (curr>num-1) curr--; } } } /* The following functions return: the editor view to go to line+column (returned by reference) editor view=NULL always means don't change cursor position! */ QEditorWidget* CGlobalCursorPosHistory::NavigateBack(int &line, int &column) { if (num<=0) return NULL; // NULL: No History Entries exist yet, Navigation not possible if (curr>=1) curr--; line =m_hist[curr].LineCol / 256; column=m_hist[curr].LineCol % 256; return m_hist[curr].FileId; } QEditorWidget* CGlobalCursorPosHistory::NavigateForward(int &line, int &column) { if (num<=0) return NULL; // NULL: No History Entries exist yet if (curr<num-1) curr++; line =m_hist[curr].LineCol / 256; column=m_hist[curr].LineCol % 256; return m_hist[curr].FileId; } QEditorWidget* CGlobalCursorPosHistory::NavigateLeave(int &line, int &column) //PUSH { if (num<=0) return NULL; // NULL: No History Entries exist yet, Navigation not possible // PUSH curr ON stack // make space for one entry at 0 memcpy((void*)&m_stack[1],(void*)&m_stack[0], (GCPH_HSTACK-1)*sizeof(CursHistEntry)); m_stack[0].LineCol=m_hist[curr].LineCol; m_stack[0].FileId =m_hist[curr].FileId; num_s++; if (num_s>GCPH_HSTACK) num_s=GCPH_HSTACK; num--; return NavigateBack(line,column); // new position is curr-1 } QEditorWidget* CGlobalCursorPosHistory::NavigatePop(int &line, int &column) //POP { if (num_s<=0) return NULL; // NULL: stack empty, Navigation not possible // get topmost stack entry (=m_stack[0]) line =m_stack[0].LineCol / 256; column =m_stack[0].LineCol % 256; QEditorWidget* p=m_stack[0].FileId; // insert the entry in history list CursorChanged(p,line,column); // delete topmost stack entry (=m_stack[0]) memcpy((void*)&m_stack[0],(void*)&m_stack[1], (GCPH_HSTACK-1)*sizeof(CursHistEntry)); num_s--; return p; }
// CURSHIST.H #ifndef CURSHIST_H #define CURSHIST_H // written by (C) Andreas Brändle <abraendle@gmx.de> 10.01.04 // published under GPL // TODO: Implement this useful feature also into other IDEs/editors!! /* You need: * 4 application-global keys: Left, Right, Up, Down (Light-version 2 keys: Right, Left -also possible) * one application-global object of this class * the editor-views must know about this object and inform it when the cursor position has changed, because - a character was entered - cursor keys pressed especially NOT when - Page/UpDown pressed - Mouse clicked also when a file/view is closed * catch the events for the 4 keys globally and change to the appropriate view+cursorposition thats all... */ // TODO: IMPORTANT! change the "QEditorWiget*"-pointers to what is needed to identify the view! class QEditorWidget; //DEL THIS LINE!! /**INTERNAL**/ struct CursHistEntry { QEditorWidget* FileId; int LineCol; // (Line 0..2^24-1) *256 + Column 0..255 to save memory }; const int GCPH_BLOCK=7; // num of lines within which a cursor movement is not to be stored twice const int GCPH_HISTSZ=260; // size of history list const int GCPH_HSTACK=16; // size of history stack /***BEGIN****/ /* Purpose: Implements a global cursor position history */ class CGlobalCursorPosHistory { public: CGlobalCursorPosHistory(); ~CGlobalCursorPosHistory(); // store/update positions void CursorChanged(QEditorWidget* FileId, int line, int column); // inform this class! void FileClosed(QEditorWidget* FileId); // clean up history list // get new position QEditorWidget* NavigateBack(int &line, int &column); // Ctrl-Alt-Left for example QEditorWidget* NavigateLeave(int &line, int &column); // Ctrl-Alt-Up for example QEditorWidget* NavigateForward(int &line, int &column); // Ctrl-Alt-Right for example QEditorWidget* NavigatePop(int &line, int &column); // Ctrl-Alt-Down for example private: CursHistEntry* m_hist; CursHistEntry* m_stack; int num; // number of valid entries int curr; // entry with last known cursor position (current) int num_s; // number of valid entries in stack }; /****END*****/ #endif CURSHIST_H
the class itself is rather simple not much is needed apart from 4 keys & the ability to set a specific view+line+column
"Also, History Back/Forward buttons will helps along with this "hypercode" walking." in Bug 62711
you don't understand this feature... or why is nobody interested??? it's such a nice feature for an editor, IMHO...
No idea why this was put to the bookmarks plugin. Also, the patch seems to reference the QEditor, which has been removed. Closing.