Thread: Managing Tabs

  1. #1
    Registered User
    Join Date
    Aug 2009
    Posts
    198

    Managing Tabs

    I am having a big problem with tabs in my text editor. If they would be all the same size, that would be OK. I put a vis_len member into my linked line struct along with len. The problem is that their size may vary depending on where they are put. So I made the add/remove character functions count up to the next multiple of 8 from the column position and add/remove the amount of iterations to vis_len. Then I thought, what if there are tabs before this tab! that would make it so that the size of previous tabs is not taken into account, and mess everything up. I have no idea what to do now.

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    A tab is typically around 4 characters positions. Some apps let you specify the size of a tab.

    Let's say you pick 4 characters for your tab length. Take the current column number, subtract 1 and mod 4, and that's how many positions you need to skip.

    For example, if the caret is in col 1 (first column). 1 - 1 = 0, 0 mod 4 is 0 -> so you add 4-0, or 4 blanks.

    If in col 2, 2-1=1, 1 mod 4 is 1, 4-1 = 3 -> add 3 blanks.

    If col 48, 48-1 = 47. 47 mod 4 = 3, 4-3 = 1 -> add 1 blank.

    etc.

    So, ignore any previous tabs - they are already taken care of. Just worry about the current col number when the tab key is pressed.
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by MTK View Post
    I am having a big problem with tabs in my text editor. If they would be all the same size, that would be OK.
    Tabs are all the same size, at least on Unix/Linux platforms, and visually appear to take up 8 whitespaces.
    Quote Originally Posted by MTK View Post
    I put a vis_len member into my linked line struct along with len. The problem is that their size may vary depending on where they are put. So I made the add/remove character functions count up to the next multiple of 8 from the column position and add/remove the amount of iterations to vis_len.
    I'm not sure what the above means; perhaps you could clarify by posting the code alongwith an example of what the expected output should be and what it really is.
    Quote Originally Posted by MTK View Post
    Then I thought, what if there are tabs before this tab! that would make it so that the size of previous tabs is not taken into account, and mess everything up. I have no idea what to do now.
    Strip the input of all tabs, replacing them with spaces. Doing it this way preserves the format because even tho' a tab is a single character, visually it takes up 8 spaces.

  4. #4
    Registered User
    Join Date
    Aug 2009
    Posts
    198
    Quote Originally Posted by Dino View Post
    A tab is typically around 4 characters positions. Some apps let you specify the size of a tab.

    Let's say you pick 4 characters for your tab length. Take the current column number, subtract 1 and mod 4, and that's how many positions you need to skip.

    For example, if the caret is in col 1 (first column). 1 - 1 = 0, 0 mod 4 is 0 -> so you add 4-0, or 4 blanks.

    If in col 2, 2-1=1, 1 mod 4 is 1, 4-1 = 3 -> add 3 blanks.

    If col 48, 48-1 = 47. 47 mod 4 = 3, 4-3 = 1 -> add 1 blank.

    etc.

    So, ignore any previous tabs - they are already taken care of. Just worry about the current col number when the tab key is pressed.
    To be sure, the "col" in your examples is the character index, and not the visual column?

    Quote Originally Posted by itCbitC
    Tabs are all the same size, at least on Unix/Linux platforms, and visually appear to take up 8 whitespaces.
    That's just not right. See this:

    Code:
    text	tab
            tab
    The first tab takes up 4 visual chars, and the second one takes 8. That's because instead of being fixed to 8 chars long, they move on until they hit the next multiple-of-8 column.

    I tried this in gedit, nano, and vi.
    Last edited by MTK; 09-14-2009 at 05:17 AM.

  5. #5
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Quote Originally Posted by MTK View Post
    To be sure, the "col" in your examples is the character index, and not the visual column?
    Correctamundo.
    Mainframe assembler programmer by trade. C coder when I can.

  6. #6
    Registered User
    Join Date
    Aug 2009
    Posts
    198
    It works, but through all the cursor movements and character insertion/deletions, it is almost impossible to keep the column and visible-column values in sync, and if it can be done, it seems like it would be a big, unelegant, and unreadable mess. I decided to better organize the data I made a text editor struct and will implement functions on it (kind of object-oriented, like with my linked_line's). I still wonder how to manage cursor movement through all those tabs.

    Code:
    #include <ncurses.h>
    #include "linked-line.h"
    
    struct text_editor {
    	LINKED_LINE* ll;                  //Linked list of char*'s for lines
    	char* filename;                   //Name of file to save to
    	unsigned long line;               //Line
    	unsigned long col;                //Index column
    	unsigned long vis_col;            //Visible column
    	unsigned long scroll;             //Vertical scroll
    	unsigned long hscroll;            //Horizontal scroll
    	unsigned long last_line_modified; //Last line that was modified
    	char saved;                       //Whether this file was saved
                                              //since last edit
    };
    
    typedef struct text_editor TEXT_EDITOR;
    Last edited by MTK; 09-14-2009 at 07:23 AM.

  7. #7
    Registered User
    Join Date
    Aug 2009
    Posts
    198
    I finished the editor, but it ended up not working at all.

    In the end I saw that Dino's technique actually relies on the visible column, and not the character index as he said. (It sounded kinda impossible to me in the first place, but he said so and I did it)

    That aside, if I insert a character to the in before of a tab, it turns out that all the tab sizes to the right all become invalid and somehow will need to be recalculated.

  8. #8
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by MTK View Post
    To be sure, the "col" in your examples is the character index, and not the visual column?



    That's just not right. See this:

    Code:
    text	tab
            tab
    The first tab takes up 4 visual chars, and the second one takes 8. That's because instead of being fixed to 8 chars long, they move on until they hit the next multiple-of-8 column.

    I tried this in gedit, nano, and vi.
    A tab takes up 8 spaces "prorated" ie if there is text before it in the 8 cols then it will stop at the next tab stop plus one. That said if col1 and col2 have characters then hitting the tab key will position the cursor at col 9 ie it takes up the remaining 7 spaces. So your assumption is correct that the position of the cursor needs to be recalculated. For ex. if you are on a line, column 68 then hitting the tab key will position the cursor at the column 73 (one more than the tab stop at column 72).

  9. #9
    Registered User
    Join Date
    Aug 2009
    Posts
    198
    I fixed it by using Dino's equation with the visual column instead if the array index and recalculating the length of the tabs in the rest of the line if a char is inserted.

  10. #10
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    I obviously misunderstood the question - glad you figured it out. Sorry for the time wasted. You're welcome for all the tips!

    I'm thinking the length of the tabs only needs to be recalced for the first tab to be "pushed" to the right, and only up to when the "pushing" stops, due to another tab that had enough pad room to its left.
    Last edited by Dino; 09-15-2009 at 05:10 PM.
    Mainframe assembler programmer by trade. C coder when I can.

  11. #11
    Registered User
    Join Date
    Aug 2009
    Posts
    198
    That's OK - The equation works when fed the display column, and I managed to do that. The basic editing functionality is almost done - including tabs.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 04-02-2009, 04:40 AM
  2. deliverance from complicated programing languages?
    By sept in forum A Brief History of Cprogramming.com
    Replies: 79
    Last Post: 02-28-2008, 12:44 AM
  3. Tabs or Spaces
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 46
    Last Post: 04-08-2007, 11:45 AM
  4. I need to use dialogs as tabs?
    By BenPage in forum C++ Programming
    Replies: 1
    Last Post: 08-03-2005, 08:59 AM
  5. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM