Programming thread

my shits fucked
it's a common thing that happens when programming: you're working on something, you think you're really smart and have good abstractions, and then... everything turns into spaghetti and the cool thing you just built falls over in a pile of scrap
DO NOT GIVE UP!
you haven't lost yet; just pick up the pieces, figure out what might have went wrong, and rewrite things without biting off more than you can chew
 
I tried rust a bit today, and their use of monads with the errors or result types pretty grating. It reminded me too much of optional in Java or bad JavaScript async code.
Compiler suggestions were also really atrocious, multiple of cargo’s “fixes” for my awful code would have introduced build errors.
I find the borrow checker and lifetime stuff interesting conceptually, but kind of annoying in practice. The former in particular is a very interesting concept but is kind of squandered on this application.

Aside from initial confusion with the syntax and borrowing semantics, I didn’t find it terribly complicated, but I did feel almost exhausted from the effort. I still have yet to see what the borrow checker provides that best practices in C cannot, and I certainly see absolutely no reason to use rust over something like modern C++. It really does feel like a language geared toward people who cannot handle memory access conceptually.

If there’s something I’m misunderstanding, feel free to give me trash cans, but I’m at a loss
 
If there’s something I’m misunderstanding, feel free to give me trash cans, but I’m at a loss
in my limited knowledge, no. rust niggers are really pushing a weird version of c++ that is retardedly strict about its smart pointers as god's gift to programming that will save the world
 
in my limited knowledge, no. rust niggers are really pushing a weird version of c++ that is retardedly strict about its smart pointers as god's gift to programming that will save the world
After writing that post, I stopped and thought to myself “what would rust need to actually be able to replace C?”
Everything I could come up with would qualify as extremely “unsafe”, in their parlance. Rust is fundamentally gimped by its own premise, it will never replace C or C++.

Also, I take really deep issue with a language marketing itself as “safe”. The people who flock to rust are going to introduce so many bugs or issues that cannot be statically detected, and they’ll have a base assumption that what they’re doing is “safe”.
There is no such thing as “safe” in programming, at least insofar as any software complicated enough to warrant consideration. There’s “safer” but there’s no safe, it’s the Wild West.
 
does anyone know how pads work in curses, the documentation tells me all but nothing and im running into visual bugs trying to use it.
for a bit of clarification, right now i want to use pads because theoretically using pads will allow for multiple screens in one terminal in the future which is a feature i'd appreciate, its a scrolling box which makes it useful for displaying text which may be longer than the terminal screen and i can specify where i want it to be which is useful for the aforementioned multiple pad concept.

the issue im having is that the pad isnt behaving at all...
Python:
def buffer_renderer(screen, buffer: list, row: int, column: int, r_offset: int, c_offset: int):
    """This function handles rendering whats in the buffer to the terminal screen.
       It loops through each row and adds a buffer row to represent it.

       If the buffer rows extend past the length of the buffer,
       it moves the screen down by a row and clears the screen.

       For each character column, offset by the horizontal scroll (c_offset),
       it tries to render the character from the buffer.
       If the buffer column is out of bounds for a given row (e.g., the line is shorter than the visible width),
       it skips rendering at that position, leaving the rest of the screen cell empty or cleared."""
   
    for rw in range(row):
            buffer_row = rw + r_offset
            if buffer_row >=len(buffer):
                screen.move(rw, 0)
                screen.clrtoeol()
                continue

            for cl in range (column):
                buffer_column = cl + c_offset
                screen.move(rw, cl)
                try:
                    screen.addch(rw, cl,buffer[buffer_row][buffer_column])
                except IndexError:
                    break
                except curses.error:
                    pass
            screen.clrtoeol()

    pass
my original buffer renderer looped through each visible row and created a buffer row to represent it so that it could be rendered if the buffer row was greater than the size provided to it it would move the cursor down the screen by one row and clear it then continue the loop it then looped through each column and did basically the same thing then it tried to render the line given the row and column currently occupied and adding whatever the corresponding character was in the buffer at that position and caught index and curses errors and then cleared the screen again simple, elegant and most importantly it worked.

now the documentation for the curses pad says that the only difference between a pad and a window is that you need to refresh the pad manually.
heres the actual documentation for the pad:
and this is the documentation for refresh:

now maybe im retarded but this solution should work:
Python:
class ContentBufferWindow:
    """This class will create a curses.pad will be responsible for housing and displaying the workable area of the tezxt editor.
    NOTE(
    Ideally i want to be able to create multiple pad instances in the same manager
    )"""

    def __init__(self,  buffer, cursor, width, height):
        self.buffer = buffer
        self.cursor = cursor
        self.width = width
        self.height = height
        self.pad_height = max(len(self.buffer) + 50, self.height)
        self.pad = curses.newpad(self.pad_height, width)
   
    def content_renderer(self):
        self.pad.clear()
        for rw in range(self.pad_height):
            buffer_row = rw + self.cursor.row
            if buffer_row >=len(self.buffer):
                self.pad.move(rw, 0)
                self.pad.clrtoeol()
                continue
                #break
            for cl in range (self.width):
                buffer_column = cl + self.cursor.column
                self.pad.move(rw, cl)
                try:
                    self.pad.addch(rw, cl,self.buffer[buffer_row][buffer_column])
                except IndexError:
                    break
                except curses.error:
                    pass
            self.pad.clrtoeol()
            try:
                self.pad.refresh(
                self.cursor.row_offset,
                self.cursor.column_offset,
                0, 0,
                self.height - 1,
                self.width - 1
                )
            except curses.error:
                pass
    pass
but it doesnt work, it wont update at all until i move my cursor or try to add text and i say try because when i do try and add text it doesnt render to the terminal. not to meantion it does this weird thing where if i move to a line with a bunch of text and go to say the middle of that text and then i move up into a line with no text at all and try to type the words will show up at the beginning of the row and if i try to delete i get an index error which i find strange and thought would be fixed by using the pad but its not.
all in all im thoroughly confused and would really appreciate some insight. the documentation doesnt give away much and theres basically one video on youtube that goes over this feature and its not much help either.
heres the code in its entirety if youre interested in the wider context. do note that its currently using the old system as ive commented out the pad class in order to continue using the editor to document my issues



Python:
import curses
import sys
import os
from dataclasses import dataclass

# Shortcut Dictionary
shortcutKeys={}
def debug_buffer_to_file(buffer, filepath="debug_log.txt"):
    with open(filepath, "w", encoding="utf-8") as f:
        for i, line in enumerate(buffer):
            text_line = "".join(chr(c) for c in line)
            ascii_line = " ".join(str(c) for c in line)
            f.write(f"{i:03d}: {text_line}\n")
            f.write(f"     ASCII: {ascii_line}\n")
def window_init():
    pass

def load_file(buffer, filepath):
    """
    This function opens a file provided by the user,
    converts the lines from standard strings to a series of characetrs which are easier,
    for our buffer array to keep track of and modify.
    After converting the lines they're loaded into the buffer for modification.
    (this uses a nested for that loops through the lines array creating an ascii line array to store the asci data
    It then loops through the individual lines and converts them to their ascii numbers
    After which the ascii line array is stored in the buffer)
    """
    #[1}basic error catching system which "tries" to open a provided file

    try:
        with open(filepath, "r", encoding="utf-8")as file:
            lines = file.read().splitlines()
            for line in lines:
                ascii_line = []
                for char in line:
                    ascii_line.append(ord(char))
                buffer.append(ascii_line)

    #{2] if it cannot open the file it will print an error message and then create a blank line instead of crashing the program.

    except (FileNotFoundError, PermissionError) as e:
        print(f"[!] Could not open file '{filepath}': {e}")
        buffer.append([])        
    return buffer
           

def save_file(buffer, filepath):
    """This function opens the file provided by the user,
    Converts the lines found in the buffer back to standard strings,
    after which it writes these lines to the file and closes it"""

    content = ""
    for line in buffer:
        for column in line:
          content += chr(column)
        content += "\n"
       
    with open(filepath, "w", encoding="utf-8") as file:
        file.write(content)


def buffer_renderer(screen, buffer: list, row: int, column: int, r_offset: int, c_offset: int):
    """This function handles rendering whats in the buffer to the terminal screen.
       It loops through each row and adds a buffer row to represent it.

       If the buffer rows extend past the length of the buffer,
       it moves the screen down by a row and clears the screen.

       For each character column, offset by the horizontal scroll (c_offset),
       it tries to render the character from the buffer.
       If the buffer column is out of bounds for a given row (e.g., the line is shorter than the visible width),
       it skips rendering at that position, leaving the rest of the screen cell empty or cleared."""
   
    for rw in range(row):
            buffer_row = rw + r_offset
            if buffer_row >=len(buffer):
                screen.move(rw, 0)
                screen.clrtoeol()
                continue

            for cl in range (column):
                buffer_column = cl + c_offset
                screen.move(rw, cl)
                try:
                    screen.addch(rw, cl,buffer[buffer_row][buffer_column])
                except IndexError:
                    break
                except curses.error:
                    pass
            screen.clrtoeol()

    pass

def visual_cursor_renderer(screen, row, row_offset, column, column_offset):
        """This function handles rendering the visual cursor
        The visual cursor is the cursor found inside the terminal"""
        try:
            curses.curs_set(0)
        except curses.error:
            pass
       
        # Tell curses where to draw the visual cursor, based on scroll offset and logical cursor
        screen.move(row - row_offset, column - column_offset)

        try:
            curses.curs_set(1)
        except curses.error:
            pass

        #NOTE: This refresh might be unnecessary, will remove later
        #screen.refresh()

class StatusWindow:
    """This class will house a simple window which displays various important pieces of information about a specific file
    NOTE(
    I may want to rename this and make it also responsible for any commands I want to implement in the future
    )"""

    def __init__(self,width):
        pass


class ContentBufferWindow:
    """This class will create a curses.pad will be responsible for housing and displaying the workable area of the tezxt editor.
    NOTE(
    Ideally i want to be able to create multiple pad instances in the same manager
    )"""

    def __init__(self,  buffer, cursor, width, height):
        self.buffer = buffer
        self.cursor = cursor
        self.width = width
        self.height = height
        self.pad_height = max(len(self.buffer) + 50, self.height)
        self.pad = curses.newpad(self.pad_height, width)
   
    def content_renderer(self):
        self.pad.clear()
        for rw in range(self.pad_height):
            buffer_row = rw + self.cursor.row
            if buffer_row >=len(self.buffer):
                self.pad.move(rw, 0)
                self.pad.clrtoeol()
                continue
                #break
            for cl in range (self.width):
                buffer_column = cl + self.cursor.column
                self.pad.move(rw, cl)
                try:
                    self.pad.addch(rw, cl,self.buffer[buffer_row][buffer_column])
                except IndexError:
                    break
                except curses.error:
                    pass
            self.pad.clrtoeol()
            try:
                self.pad.refresh(
                self.cursor.row_offset,
                self.cursor.column_offset,
                0, 0,
                self.height - 1,
                self.width - 1
                )
            except curses.error:
                pass
    pass

class WorkspaceManager:
    """This class will manage:
    >>The different windows created,
    >>inputs passed
    >>Commands maybe?(not sure yet)
    >>etc(ill update as i go along)"""
    def __init__(self,):
        pass

@dataclass(slots=True)
class Cursor:
    """This class handles Cursor initialization and application.
    It needs to be aware of the cursors logical position, meaning its position within the editors buffer
    COMPONENTS:
    >> buffer         : A reference to the text buffer (a list of strings), allowing the cursor to interact with document content.
    >> row            : The current logical row index within the buffer.
    >> column         : The current logical column index within the current buffer row.
    >> row_offset     : The number of rows the screen has scrolled down from the top of the buffer; determines vertical viewport start.
    >> column_offset  : The number of columns the screen has scrolled right from the start of each line; determines horizontal viewport start.
    """

    buffer: list
    row_offset: int = 0
    row: int = 0
    column_offset: int = 0
    column: int = 0
       
    def cursor_scrolling(self, term_column, visible_rows):
        """This function takes the available column and row space and moves the visual and logical terminal between its boundries"""

        if self.column < self.column_offset:
            self.column_offset =self.column
        if self.column >= self.column_offset + term_column:
            self.column_offset = self.column - term_column +1

       
        if self.row < self.row_offset:
            self.row_offset = self.row
        if self.row >= self.row_offset + visible_rows:
            self.row_offset = self.row - visible_rows +1

    def cursor_actions(self, ch):
        """This Function takes the character recieved from getch()
        If the character is an arrow key it moves both the visual and logical cursor to the new position"""
       
        #LeftMovement
        if ch == curses.KEY_LEFT:
            if self.column !=0:
                self.column -=1
            elif self.row > 0:
                self.row -=1
                self.column = len(self.buffer[self.row])

        if ch == curses.KEY_RIGHT:
            if self.column < len(self.buffer[self.row]):
                self.column+=1
            elif self.row<len(self.buffer)-1:
                self.row +=1
                self.column = 0

       
        if ch == curses.KEY_UP:
            if self.row >0:
                self.row -=1
                #self.column = len(self.buffer[self.row])
        if ch ==curses.KEY_DOWN:
            if self.row < len(self.buffer)-1:
                self.row +=1
                #self.column = len(self.buffer[self.row])

def main(stdscr):
    # Initialize the screen
    #NOTE(
    # WILL MAKE A SPECIFIC FUNCTION FOR SCREEN INITIALIZATION
    #)

    mainscreen = stdscr            
    curses.noecho()             # Makes it so that non letter inputs arent displayed on the screen when typing
    curses.raw()                # Make it so that characters are recieved as the are sent to the terminal
    mainscreen.keypad(1)            # Enables the special keys like arrows and whatnot
   

    buffer = []

   
    src ='noname.txt'                                        # Sets the default file name
    (term_row,term_column)=mainscreen.getmaxyx()                  # Sets the terminal dimensions
    visible_rows = term_row-1                               # Sets aside a row for the line indicator/bottom info giver thingy
   
    cursor = Cursor(buffer=buffer)         # Creates and store the cursor in its own class
    #content_window = ContentBufferWindow(buffer=buffer, cursor= cursor, width= term_column, height=term_row)
    # Handles file loading
    if len(sys.argv) ==2:
        src = sys.argv[1]
        load_file(buffer, src)        
   
   
    #NOTE(
    # Not sure i need this waiting to see if this breaks an edge case or something
    # The video i followed didnt go into great detail on why choices were made so i just keep commenting things out to text their usefullness
    # Hence large blocks of commented out code may be found all about the program thee will be removed eventually.
    #)

    while True:
        #mainscreen.move(0,0)   #positions the cursor to top left

        #SCROLLING
        cursor.cursor_scrolling(term_column=term_column, visible_rows= visible_rows)


        #SCREEN RENDERING
        buffer_renderer(screen= mainscreen, buffer=buffer, row=visible_rows, column=term_column, r_offset=cursor.row_offset, c_offset= cursor.column_offset )
        #content_window.content_renderer()
        debug_buffer_to_file(buffer=buffer)
        #STATUS BAR NOTE: Soon to be status window.
        status = f"{cursor.row+1}/{len(buffer)}  Col:{cursor.column+1}  {int((cursor.row+1)/len(buffer)*100)}%                                      {src}"
        mainscreen.addstr(term_row - 1, 0, status[:term_column-1], curses.A_REVERSE)
       
       
        #CURSOR RENDERING
        visual_cursor_renderer(screen=mainscreen, row= cursor.row, column= cursor.column, row_offset= cursor.row_offset, column_offset= cursor.column_offset)
        #screen.refresh()
       
       

        #input manager
        ch =mainscreen.getch()

        #Text insert  
        if ch != ((ch) & 0x1f) and ch < 128:
            buffer[cursor.row].insert(cursor.column, ch)
            cursor.column +=1

        #enter handling  
        if chr(ch) in "\n\r":
            line = buffer[cursor.row][cursor.column:]
            buffer[cursor.row] = buffer[cursor.row][:cursor.column]
            cursor.row+=1
            cursor.column = 0
            buffer.insert(cursor.row, line)
       
        #Backspace handling
        if ch in [8,263]:
            if cursor.column:
                cursor.column -=1
                del buffer[cursor.row][cursor.column]
            elif cursor.row>0:
                line = buffer[cursor.row][cursor.column:]
                del buffer[cursor.row]
                cursor.row -=1
                cursor.column = len(buffer[cursor.row])
                buffer[cursor.row] += line

        #CURSOR ACTIONS    
        cursor.cursor_actions(ch=ch)

       


        #NOTE: NO CLUE WHAT THIS DID, MIGHT HAVE BEEN SOME LEFT OVER CODE DEALING WITH BUFFER RENDERING
        #if cursor.row < len(buffer):
            #rw = buffer[cursor.row]
        #else:
            #None
        #rwlen = len(rw) if rw is not None else 0
        #if cursor.column >rwlen:
            #cursor.column = rwlen

        #save and quit
        if ch == (ord("s") & 0x1f):  # Ctrl+S
            save_file(buffer=buffer, filepath=src)

        if ch == (ord("q") & 0x1f):  # Ctrl+Q
            sys.exit()


curses.wrapper(main) #this protects the terminal
 
Last edited:
what's stopping you from eschewing pads and just doing the scrolling and text printing inside the window by yourself?
potential optimization: i think curses has a function to move chunks of the window around that it can do faster than you on certain specific terminals (but it's not very important, computers are fast)
 
“what would rust need to actually be able to replace C?”
rust is more of a c++ replacement, but nowadays they're very similar in terms of smart pointers and etc
except that c++ compilers arent pissy
a more apt c replacement would be zig
but zig is fucking opinionated as fuck so it wont replace c anytime soon

quite frankly i think just the sheer idea of "dethroning" c/c++ is retarded, these languages have been used for pretty much everything for the past ~50 years, that's why lingua franca of programming is c, every language that wants to interface with other languages has to be able to interface with c
basically we're too far gone, that's like making a search engine and calling it a google killer
 
a more apt c replacement would be zig
but zig is fucking opinionated as fuck so it wont replace c anytime soon
it is also one of those languages that seems to be really early in development so you don't have a historical body of zig shit, a cultural knowledge of the language's flaws, a decentralized community, and random retards writing zig compilers for fun, the latter two of which i feel are a sort of litmus test to know if a language has a nice combination of stability and simplicity
quite frankly i think just the sheer idea of "dethroning" c/c++ is retarded
c might be replaceable but it's stupid to try to replace it with something that's almost exactly like c but with a couple of things you think are shit removed from the language
i mean it would be nice to remove the shit parts of c because they absolutely do exist (people who think c is the global optimum of systems programming are hopelessly retarded) but it needs to be good enough that people decide "yes i think i will use c+=blackjackandhookers instead of c for this project because i like how it has that safe integer arithmetic with optional compiler assisted ridiculously fast bignum support, and i would also like to use the standard library hash map and standard random functions, and i really like the little feature it has for automatic memory jannying"
every language that wants to interface with other languages has to be able to interface with c
counterpoint: stuff that runs on well-known runtimes that aren't the usual posix systems, like the jvm, clr, and stuff that compiles to javascript
some of these runtimes have c ffi but the languages themselves don't really give that much of a fuck what's going on in c land
 
I mean opinions aren't bad unless they're bad opinions but the way you guys talk, you don't think they're good opinions, right?
yeah
people had to whine for a while to get c style for loop in the language
indentation by tab is straight up prohibited
zig compiler shits itself when it encounters a tab anywhere (except comments, they've fixed that)
1749299089037.webp
zig compiler shits itself when there's an unused variable
and other pretty niggerlicious shit

also i find this very ugly
1749299224438.webp
 
I mean opinions aren't bad unless they're bad opinions but the way you guys talk, you don't think they're good opinions, right?
guess
99% of the time you see something being "opinionated" you see a complete retard who adds 5 random features and completely cripples everything else because by god you're going to use the 5 random meme features in their shitty language
and these features are never anything good and they never let you easily fake a concept you would actually like to use because 21st century language designers are actually fearful of giving power to the user (the trend these days is to file off all the corners so nobody ever runs the risk of hurting themselves or making a program that doesn't look exactly the same as all the other programs)
then they wonder why it's only used in its own compiler and a few random toy programs
people had to whine for a while to get c style for loop in the language
did he spend 6 years saying "no child you need to use my genius iterator feature" because he made a stupid iterator feature and really wants everybody to use it
indentation by tab is straight up prohibited
zig compiler shits itself when it encounters a tab anywhere (except comments, they've fixed that)
bruh add \t to the whitespace parser rule what the fuck is blud smoking 💀💀💀 oh god this language is so stupid i randomly started speaking niglish somebody please help me
anyway this just proves my point about languages these days aggressively trying to cripple themselves so the user can't do anything the language designer doesn't agree with
also i find this very ugly
1749299224438.webp
nice syntax, i hope making your stupid fucking module system have the modules look like variables proved something to somebody

anyway i blame python for being the inspiration behind all these shitty new languages being "opinionated"
 
Henlo all. Long time retard, first time poster here. I've been trying for years to get into programming but there's always a point that after reading or online videos/classes my eyes go glassy and I just fall out of it. I think it's because I'm just doing school work and not doing anything. I also might be an undisciplined idiot and this was never gonna work. Are there any projects that you would be able to recommend to me that I can learn by writing it? I wanted to at least try and reach out to people who know before I gave up.
 
bruh add \t to the whitespace parser rule what the fuck is blud smoking 💀💀💀 oh god this language is so stupid i randomly started speaking niglish somebody please help me
anyway this just proves my point about languages these days aggressively trying to cripple themselves so the user can't do anything the language designer doesn't agree with
you can use \t
you cannot use raw tab
im not saying its good to use it, but still, there's no reason for the parser to shit itself when it encounters a tab space anywhere where it would encounter a normal space or a newline
 
bruh add \t to the whitespace parser rule what the fuck is blud smoking 💀💀💀 oh god this language is so stupid i randomly started speaking niglish somebody please help me
anyway this just proves my point about languages these days aggressively trying to cripple themselves so the user can't do anything the language designer doesn't agree with
you can use \t
you cannot use raw tab
im not saying its good to use it, but still, there's no reason for the parser to shit itself when it encounters a tab space anywhere where it would encounter a normal space or a newline
Yeah this shit screams "HELP! I DON'T KNOW HOW TO WRITE A PARSER!!!" so loudly it deafens me.

Henlo all. Long time retard, first time poster here. I've been trying for years to get into programming but there's always a point that after reading or online videos/classes my eyes go glassy and I just fall out of it. I think it's because I'm just doing school work and not doing anything. I also might be an undisciplined idiot and this was never gonna work. Are there any projects that you would be able to recommend to me that I can learn by writing it? I wanted to at least try and reach out to people who know before I gave up.
 
Henlo all. Long time retard, first time poster here. I've been trying for years to get into programming but there's always a point that after reading or online videos/classes my eyes go glassy and I just fall out of it. I think it's because I'm just doing school work and not doing anything. I also might be an undisciplined idiot and this was never gonna work. Are there any projects that you would be able to recommend to me that I can learn by writing it? I wanted to at least try and reach out to people who know before I gave up.
try smashing some shit together with one eye on the terminal/editor and the other eye on the docs instead of absently watching some negative charisma pajeet on youtube do it when you could be doing it
as for things to do you can literally do whatever the fuck you think would be neat to do, like how user @ChudJack009 is making his own text editor. he's using only a shitty barebones editor he copy pasted, rudimentary python understanding, and high-grade autism and he's learning quick because he's actually doing things and also people here can help him because he's actually doing things
you can use \t
you cannot use raw tab
im not saying its good to use it, but still, there's no reason for the parser to shit itself when it encounters a tab space anywhere where it would encounter a normal space or a newline
i know you can use the \t escape but i was saying that these guys didn't add the \t to the list of characters their parser considers to be whitespace
im not opposed to beginners posting here as long as they are like @ChudJack009 and not "hello guys how do i learn code" because only one of them can receive help from this thread
Someone should make a +NIGGER patch to change opinions to warnings and rename the project "nig".
tab shouldn't be a warning, if i want to use unicode zero width spaces to indent i should be able to do that and not have some gay tool telling me i shouldn't indent with zero width spaces and refusing to compile my program
 
now maybe im retarded but this solution should work:
Can you paste a complete source file that has the error with the new pad class? Might be sensible to start learning git for this and put it somewhere, that way you can just reference a specific commit for "okay this commit has this bug", while still being able to roll back to a working version at need.

My first run hit a DivideByZero exception as I did not specify a file to edit. As a minimalist myself, I'm fine with eating an exception when I do something wrong like this, but adding a handler for the case where there is no file is helpful.

But the DEEPER problem here is that even a file with zero bytes will hit this error. I guess for the "no file name" case you'd need some logic for a default file name, so it is probably quicker to just halt-with-error on no-filename... ergo there's a case for not handling anything but the zero-size case.

Responsive newbies like you are fine for this thread. New comments represent new iterations. That seems a reasonable metric for "does this belong in this thread". Beginner thread is so the newbie doesn't even have to worry about "shitting the thread up" with trivial BS, IMO.
 
Back