Advice on textuser inteface modules.

This is the place for queries that don't fit in any of the other categories.

Advice on textuser inteface modules.

Postby Emilnd » Tue May 28, 2013 10:49 am

Hey everyone!

I have decided to pick up coding now after a 3 months break. What I want to do is finish a project I started on a while back and it is and text editor for use in terminals (nano, vi etc.).
The main goal I have and reason to not use named editors is that I love the typing features of http://eric-ide.python-projects.org/ and want to bring those into the terminal.
Some examples of typing feature is like:
# If you make one "(", you will automatically get both "(" and ")", and the cursor placed in the middle of them.
# When you make a ",". There will be an space inserted afterwards and the cursor is placed after it.
# If you press ctrl+d you will duplicate that whole line downwards.

These are not perhaps the best practices for overall coding but I really like it this way and don't see why I should learn any other.
Then ofcourse I would like to add some highlighting and line numbers and other basic things. In the end it will probably look like Nano with line numbers and aswell the use of wanted features..

Anyway, what I need your help for is to find a good library that can help me with this. Ofcourse the first which popped up in my head was curses and I have made a pretty good prototype with it, though curses it self seems to contain a bunch of bugs? And aswell a very incomplete set of basics? Like turn on and off insert mode! I will show you with he code I have written soon.
I have tried some urwid, but their example of a text editor is very hard to understand and when I seaked help in their irc channel they told me it was a very lazy written code, really nothing more hehe.

So I just really need advice on how I can get going. Because I really need this for use on my servers where I more and more impeltent python scripts.

Here is the prototype I have written. If you try it you will see weird things like backspace clears the whole row and some kind of insert mode is always on, which I don't use at all.
The features I have made works pretty good though, so make sure to try them out, type "," and "(" or try out ctrl+d ;)
http://pastebin.com/4uRbVu8L

I am using Python 2.7.5 on Linux.

Here is the code from pastebin
Code: Select all
# Sorry for poor documentation and at the end I probably smashed in some
# things that don't need to be here at all.

import curses, curses.textpad, curses.ascii

class sheet:
    def __init__(self, win):
        self.win = win
        self.gridY = win.getmaxyx()[0]
        self.gridX = win.getmaxyx()[1]
        win.keypad(1)
        self.win.idcok(False)
        self.win.idlok(0)
   
    def end(self, gridPosY):
        last = self.gridX
        while True:
            if curses.ascii.ascii(self.win.inch(gridPosY, last)) != curses.ascii.SP:
                print curses.ascii.ascii(self.win.inch(gridPosY, last))
                last = min(self.gridX, last+1)
                break
            elif last == 0:
                break
            last = last - 1
        return last
   
    def compose(self):
        endIndex = {}
        for i in range(0, self.gridY):
            endIndex[str(i)] = 0
        while 1:
            gridPosY, gridPosX = self.win.getyx()[0], self.win.getyx()[1]
            ch = self.win.getch()
            if ch == ord(curses.ascii.ctrl('o')):
                print self.win.inch(gridPosY, gridPosX)
            elif ch == ord(curses.ascii.ctrl('c')):
                break
            elif ch == ord(curses.ascii.ctrl('d')):
                bucket = []
                for i in range(0, self.gridX):
                    seed = self.win.inch(gridPosY, i)
                    bucket.append(seed)
                self.win.insertln()
                self.win.move(gridPosY + 1, 0)
                for i in range(0, len(bucket)):
                    self.win.addch(bucket[i])
                    if gridPosX + 1 != self.gridX :
                        self.win.move(gridPosY, i)
            elif ch == curses.KEY_END:
                last = self.end(gridPosY)
                print last
                self.win.move(gridPosY, last)
            elif ch == curses.KEY_ENTER:
                endIndex[str(gridPosY)] = gridPosX
            elif ch == curses.KEY_LEFT:
                endIndex[str(gridPosY)] = gridPosX
                if gridPosX > 0:
                    self.win.move(gridPosY, gridPosX - 1)
            elif ch == curses.KEY_RIGHT:
                endIndex[str(gridPosY)] = gridPosX
                if gridPosX + 1 != self.gridX :
                    self.win.move(gridPosY, gridPosX + 1)
            elif ch == curses.KEY_UP:
                endIndex[str(gridPosY)] = gridPosX
                if gridPosY > 0:
                    self.win.move(gridPosY - 1, endIndex[str(gridPosY - 1)])
            elif ch == curses.KEY_DOWN:
                endIndex[str(gridPosY)] = gridPosX
                self.win.move(gridPosY + 1, endIndex[str(gridPosY + 1)])
            elif ch == ord('\t'): # Tabs
                self.win.addnstr(' ', 4)
                self.win.move(gridPosY, gridPosX + 4)
            elif ch == ord('('): # (cursor)
                self.win.addstr('('), self.win.addstr(')')
                self.win.move(gridPosY, gridPosX + 1)
            elif ch == ord('"'): # "cursor"
                self.win.addstr('"'), self.win.addstr('"')
                self.win.move(gridPosY, gridPosX + 1)
            elif ch == ord("'"): # 'cursor'
                self.win.addstr("'"), self.win.addstr("'")
                self.win.move(gridPosY, gridPosX + 1)
            elif ch == ord(','): # Make space after ","
                self.win.addch(ch), self.win.addstr(' ')
                self.win.move(gridPosY, gridPosX + 2)
                #self.win.move(gridPosY, gridPosX - 1)
            elif ch in (127, curses.KEY_BACKSPACE): # Backspace
                if gridPosX > 0:
                    self.win.move(gridPosY, gridPosX - 1)
                    #self.win.delch()
                    self.win.clrtoeol()
            else:
                self.win.addch(ch)
   
    def gather(self):
        pass
        # collect and save some shit, attrs!!!!
   
    def drawInterface(self):
        myScreen_gridY, myScreen_gridX = myscreen.getmaxyx()[0], myscreen.getmaxyx()[1]
        for i in range(0, myScreen_gridY - 2 - 1):
            if i < 10:
                myscreen.addstr(2 + i, 2, str(i))
            else:
                myscreen.addstr(2 + i, 1, str(i))
        myscreen.addstr(0, 5, "EngeboEditor - v0.0.1")
        curses.textpad.rectangle(myscreen, 1, 4, myScreen_gridY - 1, myScreen_gridX - 2)
        myscreen.refresh()

myscreen = curses.initscr()
curses.noecho()
curses.cbreak()

win = curses.newwin(myscreen.getmaxyx()[0] - 3, myscreen.getmaxyx()[1] - 7, 2, 5)
win.idcok(False)
#myscreen.idlok(False)
sheet(win).drawInterface()
sheet(win).compose()

curses.endwin()
Last edited by Yoriz on Tue May 28, 2013 10:56 am, edited 1 time in total.
Reason: Added the code in code tags
Emilnd
 
Posts: 1
Joined: Mon May 13, 2013 5:31 pm

Re: Advice on textuser inteface modules.

Postby micseydel » Tue May 28, 2013 11:18 am

If I were told about this and had to get started, curses would be the first and really only thing that came to my mind. That said, have you seen this? It's just another option on top of what you mentioned you've already come across, but it's definitely another option.
Join the #python-forum IRC channel on irc.freenode.net!
User avatar
micseydel
 
Posts: 941
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA


Return to General Coding Help

Who is online

Users browsing this forum: Google [Bot] and 1 guest