« first day (1903 days earlier)      last day (92 days later) » 

4:00 PM
somewhat unrelatedly: I really need to stop RD.Parsing from always rebuilding
that should speed up running tests locally by a huge factor for satellite assemblies
hmm, not sure that's just parsing.
I've noticed that main likes to builds itself everytime, too
it's primarily parsing, because the ANTLR target doesn't do up-to-date checks
and Main is downstream from parsing, so it's most likely just cascading
yeah... I commented that because in my mocking PR where my main work is in the main, I don't see parsing rebuilding
but I seem to remember that when working in refactoring, the core (not main, sorry, bad memory) always rebuilds even though nothing changed in the core.
@Vogel612 could it be just Antlr rebuilding the grammar everytime, thus regenerating the lexer, parser, base listener, and all the generated code - prompting a rebuild of RD.Parsing?
yea, that's what I'm thinking
do we (/Antlr) define constants in RD.Parsing, that RD.Core is using? A const being rewritten would cause all referencing assemblies to rebuild
token IDs come to mind (or they're static readonly variables?)
:derp: Ctrl+R, Ctrl+R needs to be in RD for renaming variables.
nah, token IDs are static readonly
4:12 PM
oohhhhh... I know why the test fails
because the annotation itself is never constructed
@IvenBach hotkey "chords" have been on the wishlist forever! :)
I suspect it'll get easier with custom code panes
then we wouldn't have to fight with VBIDE.... right?
Q: Step by Step, ooh HotKey

Mathieu GuindonStill hooked on Windows, I refactored the hook into a number of interfaces, and I wanted to support 2-step hotkeys, so I started with defining an IHook that can be attached, detached, exposes a property that tells whether a hook is attached or not, and raises an event when the hook receives a mes...

As much as VS makes me feel dumb and makes me struggle to learn new things It's a whole lot better than the VBA IDE.
4:14 PM
TBH, I find VS has too much tooling. I only use a little bit of it.
it never really worked though, and then hotkeys were pretty much entirely rewritten
I'm sure it's all used, but I basically use the watch, the locals, the source control, and the code panes
"Class View" baffles me. Why would I need that on top of the Solution Explorer?
because you love UML?
It's basically the object explorer.
I actually didn't know about that one.
But it lets you see dependency structures.
4:16 PM
well it's basically namespace-driven, whereas solution explorer is file-system driven
Like, in the web app I'm in, I can drill in and see the ANTLR3 NuGet dependency's types.
i wonder if it's driven by the partial which would diverge from the filesystem?
Double-clicking an item opens the object browser.
oh I get it - it's drilling into the inheritance hierarchy rather than the members
yeah it's like a mini-object browser
..which I suppose is useful when you're not familiar with a project
Or if you are learning a new dependency.
4:22 PM
Poke @M.Doerner the AttributeAnnotationProvider doesn't hit the Annotation Type's constructor when examining the Attribute Values
that's why the unit test you admonished fails
@IvenBach #FunFact that is exactly why the hotkey settings grid has a "Key1" heading; there's a hidden (or commented-out, I don't recall) "Key2" column that means to accept the 2nd key of a hotkey chord.
@Vogel612 The AttributeAnnotationProvider is meant to provide tha data needed to construct a suitable annotation based on the attribute and attribute value.
The second parameter in the test actually has the wrong name.
It should be attributeValue not annotationValue.
uuuuuuhhhh... okay
but then it should be @"A\n14", ..., @"A\14", because we're not constructing the annotation itself...
So far, different values either translated to another annotation type or were passed on.
the method tested is only used in the annotation quickfixes
it doesn't test whether the annotation type itself does the transformation correctly..
4:31 PM
@MathieuGuindon I know it's on the roadmap. Just wish it'd arrive sooner. Having them identical to VS would make coding so much easier.
The correct annotation value to get the attribute value @"A\n14" is "A" .
The annotation does the reverse transformation.
but the annoation ctor is never hit on that codepath
testing for it there doesn't make sense
it only finds the annotation type that needs to be constructed, but never actually constructs it
It provides the current type and argument in order to be used to update/create the annotation in the module.
yes, but the transformation happens in the associated class constructor, which is never called
at least for FlexibleValueAnnotations
It has to provide the annotation value that will lead to the attribute value provided.
4:36 PM
for FixedValueAnnotations, the value is relevant, for flexibles only the count is taken into consideration
but it doesn't... that's kinda the point
or rather... the provided value is passed through
because again: the constructor of the specific annotation class is never called on the codepath tested there
As I said, so far only the count mattered since the attribute and annotation value were always identical.
yea, but the AttributeAnnotationProvider only returns the AnnotationType, not an instance of T : IAttributeAnnotation
The new annotation is the first attribute annotation to do a transformation from the annotation value to the attribute value.
so far I'm with you
Look at where it is used.
There is no need for the instance.
4:40 PM
I still don't follow
The instance is created on the next parse
where are we constructing annotation instances?
so the AttributeAnnotationProvider is not responsible for creating instances, right?
Why are you expecting it to do that (for the value transformation) then?
would AttributeAnnotationTypeProvider be a better name for it then?
4:42 PM
        [TestCase("VB_ProcData.VB_Invoke_Func", @"A\n14", AnnotationType.ExcelHotKey, @"A\n14")]
        // ^^ this test passes
@MathieuGuindon maybe, yes
It has to provide the information required to insert code into the code pane that results in an attribute annotation corresponding to the attribute provided.
but Provider is not really a good name, considering it returns additional information (namely the number of annotation arguments to help annotation rewriting)
@M.Doerner so far nothing there says to me that it needs to instantiate the Annotation Type?
It returns the values, not the count.
and it also doesn't imply that the AttributeAnnotationProvider needs to do that transformation
Please have a look at where it is used.
If you use the AdjustAttributeAnnotationQuickFix, you will expect to get an annotation representing the attribute, right?
4:47 PM
soo ... AttributeAnnotations don't expose enough information from what I can tell...
that's why there is this weird clunky provider workaround there that for some reason interferes with the responsibilities of the annotations themselves
which means.... I gotta do some refactoring, I guess...
because as it stands Annotations only expose the AttributeValues
I've done 8 hours worth of work (based on estimates) in the last 2 hours.
I'm not sure what's more concerning.
Please note that we have no annotation at the start, only the attribute.
The fact that the estimate is that high, or the fact that I did it that fast.
notably AnnotationBase does not expose AnnotationValues (which would be more appropriately named AnnotationArguments)
@M.Doerner eww... that's kinda ugly
I mean for the business--if I became unavailable for some reason...
4:50 PM
Why should it?
we're correlating Attributes to AnnotationTypes already, which implies we should be able to construct an instance of IAnnotation
The job of the provider is to reverse engineer the annotation from the attribute.
tightly correlating the metainformation to a VBAParser context isn't correct here
But we do not need an instance.
but that's where the value transformation is...
that's the whole point of this mess...
4:52 PM
But it is the reverse transformation we need.
We have an AnnotationType from the Provider, the transformation must not be it's responsibility though
because the AnnotationArg -> AttributeArg transformation is the job of the Annotation instance
therefore it should also be responsible for the reverse transformation
And the provider does the reverse transformation.
but it shouldn't
4:53 PM
and testing for it when it doesn't also makes no sense
because the transformation is domain specific logic for the annotation
and it can be different for each separate annotation
It is also responsible for finding the right annotation based on the attribute in the first place.
we don't want to have a gigantic switch inside the provider to correlate annotation types to their backtransformations
@M.Doerner that's a different responsibility, though...
it's resolution / binding vs semantics
the provider binds the semantic holder to the parsed context
it's not responsible for the "runtime evaluation"
also, forgive my french, but provider is a shit name here
AttributeAnnotationTypeResolver would be more of a match to what it does right now, or am I misunderstanding again?
It got its name from the perspective of the user.
the alternative would be to augment the FlexibleAttributeValueAnnotationAttribute with the necessary metainformation to enable value transformation
which should in turn make the ExcelHotKeyAnnotation class unnecessary and allow us to seal the FlexibelAttributeValueAnnotationBase
which should of course be renamed then ...
5:00 PM
I really don't like to put too much magic into the attribute.
well, we kinda need to put it somewhere....
the alternative would be to put it in the Annotation class itself.
but putting the backtransform and the transform into different places makes no sense
So far, there was only a trivial backtransform. So I stopped at that points. The transformations of the annotation systems were already giving me enough headaches.
The question is how to put the information on the annotation
aight... Imma try digging around to find something that can simplify the overall process
the transformation stuff should probably fall in place then
Please keep in mind that the actual annotations are created via reflection.
That is why they all have the same constructor parameters.
@23fc9a62-56de-47fb-97b4-737890 be wary of papers asking for signature and including prohibitions of crossing the street near bus stops.
5:06 PM
@FreeMan Ooops.
Btw, at the end, we will still need a class that does exactly what the provider does right now.
@M.Doerner yea, I know.
@M.Doerner that class should probably do a few more things to simplify the overall process...
I think I'll look into moving away from our enum-based AnnotationType idea
that's quite a redesign though
the thing is: those enums are doing multiple things and we're like the third bolt-on in on how they work
but yeah I'm all for it - we'll be running out of int32 values with all these flags :)
@Vogel612 lol true
5:09 PM
there's special enum values for where an annotation is allowed and the AttributeAnnotations have a C# Attribute tacked on dealing with the attribute transformations
I think I want to get to automatically discovering annotation types through CW and enriching them with information instead of correlating the types we rely on anyways with an enum value
Something like:
class ExcelHotKeyAnnotation : FlexibleAttributeAnnotation
    int Arguments { get; } => 1;
    AnnotationTarget Target { get; } => AnnotationTarget.Member;
of course doing something like that implies moving the magic in the annotation system from the AnnotationType enum into the class hierarchy, but it should work
most of that information should be statically available, though...
and that makes it a bit harder to enforce in the class hierarchy...
So the alternative would be:
[FlexibleAttributeAnnotation("VB_ProcData.VB_Invoke_Func", 1)]
class ExcelHotKeyAnnotation : FlexibleAttributeAnnotation
   //  ...
but then we just moved the magic ...
hmm ... interesting ...
teh `VBAParserAnnotationFactory´ currently needs manual specification of the supported annotations and annotation types...
that'd fall away completely.
well, crap. now I'm knees deep in another large-scale refactoring :/
Okay, I'll just finish the ExcelHKAnnotation by bodging it in and then I'll do the refactor as a separate PR
@Vogel612 in soviet, the ducky refactors you. ;-)
5:28 PM
@Vogel612 Sounds good.
@this Soviet, umm, Canada?
That reminds me. Remember when Obama "programmed"?
I would like to have everything in the class hierarchy, but how will we construct the annotations based on the name of the annotation?
That was so funny. It was like watching him "weld" something.
And where will we have an overview of which annotations and categories thereof exist?
Currently, the enum is such an overview.
presumably the namespace would become the overview, kind of like inspections.concrete?
5:44 PM
Why, oh why is Step Into F8 in VBA, F11 in SSMS and F5 in VS?
Microsoft, consistency is thine name!
> Just to add a bit of complexity to the situation, ReDim allows to specify a type.
It is F11 in VS.
F5 is start debugging.
Which is execute in SSMS
My point!!!
you're correct, of course...
@M.Doerner we could actually do some more documentation generation magic to find all annotations...
@23fc9a62-56de-47fb-97b4-737890 according to this metrics, Canada is quite prosperous.
5:50 PM
@M.Doerner that's currently done in the VBAParserAnnotationFactory
the _creators there just need to be adapted to deal with annotation types that are injected
@this Are they dead in the last panel?
i interpreted as close to dead
so instead of AnnotationType.[...].ToString().ToUpperInvariant() we get annotationType.Name.Substring(0, [...]).ToUpperInvariant()
@Vogel612 ah ok
@Duga ReDim is strange.
It has an As clause, but that actually does not change the declared type.
@23fc9a62-56de-47fb-97b4-737890 Pineapple AHOY!
5:57 PM
Moreover, it can redimension a declared array before it is declared.
@M.Doerner that's why I understood that we'd need to do a separate pass to find all Redim-only variables
@M.Doerner it can literally act as / replace a Dim
@M.Doerner it can, if the array was first declared as a Variant
We don't. We just need to evaluate whether our undeclared variables are in a ReDim.
Sub test()
    Dim foo As Variant

    ReDim foo(1 To 10) As Long
    Debug.Print TypeName(foo)


    ReDim foo(1 To 20) As String
    Debug.Print TypeName(foo)


End Sub
@MathieuGuindon that begs the question ... how do Ignore annotations handle it?
5:59 PM
output is Long(), then String()
@Vogel612 handle what?
Dim foo As Long(10)
'@Ignore UnusedDeclaration
Redim foo As Long(15)
@MathieuGuindon that can only happen with Variant, though. I think even Variant() will fail to change type.
According to the spec, the declared type stays Variant; only the runtime type changes.
currently we're ignoring all inspections mentioned in an @Ignore on the declaration
@this at compile-time, yes
6:00 PM
Found an interesting statement of ambiguous meaning: My sister and I are getting married.
if ReDim can act as a declaration, does RD need to account for that or are we saying [wontfix, edge-case]
Of course, that means two marriages, but it could also imply marriage to each other.
we need to be able to account for it in order to whack people with cold fish
@23fc9a62-56de-47fb-97b4-737890 it wouldn't be ambiguous with "My sister and me", would it?
I wish it were an edge case, but basically when ReDim is declaring the variable, we treat it as undeclared
6:01 PM
@this sounds like a [wontfix]
@Vogel612 I don't think that is grammatically correct.
Me wouldn't work in this case, because you wouldn't say "Me is getting married."
@23fc9a62-56de-47fb-97b4-737890 "...are both getting married" wouldn't be ambiguous though, would it?
You say "X happened to Joe and me", because it still makes sense without the "Joe and"
@MathieuGuindon Correct.
6:03 PM
but saying "The marriage was conducted to my sister and me." is just.... weird
"oh, a Targaryen marriage!"
I almost said "consummated" but I couldn't use the "to"; only "between" which makes it unambiguous.
Well, you don't conduct a marriage to someone.
Yeah, that's my point. You can't marry passively.
(see what I did there)
6:05 PM
Sure you can.
The spouse can say "I do, and they do too."
Passive voice....
lol, no, never mind.
You are aware that even I will marry you is ambiguous, right?
@23fc9a62-56de-47fb-97b4-737890 technically none of it matters until they sign the contract :)
I guess a valid passive voice form would have to be "The preacher married me and my sister."
@M.Doerner If you can legally conduct a marriage, yes, it is.
@MathieuGuindon :D
6:07 PM
but I don't htink you can passively marry without that 3rd person to conduct the marriage.
The point being, the verb "to marry" does not really lend itself very well to passive voice.
Regarding ReDim, it is only a declaration if there is no other declaration for it. So, all we have to do to fix everything around it is to validate whether we are in a ReDim context when we find an undeclared variable and create a different declaration in that case.
but how do you guarantee that it's not declared somewhere else?
for example, you could be in a module A, hit the Redim foo, but there is a Public Foo() in module B which you have not yet parsed?
you'd need to enumerate all non-local variables in order to accurately determine that this particular Redim does not reference any one of those.
We do this in the reference resolver.
Ok, cool. As long that is known, I don't think that'll be a problem.
According to the spec, things are a bit more complicated though.
It states that it is a declaration if it does not resolve in the same module.
6:14 PM
so Redim Foo() in module A isn't same as Public Foo() in module B?
that paragraph doesn't really make sense, TBH
Better test it before putting it into the resolver logic.
agreed. wouldn't be first time docs was wrong
pondCheck: Should unit tests contain the name of the unit they're testing? Current book suggests so but that doesn't seem right as it hinders renaming.
6:28 PM
I think it is sufficient if the unit under test is in the test fixture name.
Forgot to mention this is in VBA-landia.
Whether you want to have it in the test name depends on your test framework.
If you can navigate from the result to the test, I do not think it is necessary.
However, if you can't and the fixture name also is not in the output, the name should be in there to aid finding the right test.
so I created 2 modules
the one module only has Public foo
the other module has:
Public Sub x()
    ReDim foo(0 To 1) As String

    foo(0) = "hello"
    foo(1) = "world"

    Debug.Print foo(0), foo(1)
End Sub
after running the procedure, ?typename(foo) returns String()
so I am not too convinced that the doc commenting that it only considers module variable is correct.
Re-reading the doc, I now see that "module level variables" could include the Public foo -- in actuality the doc should have had said "public module-level variables"
then the following sentence makes sense
If I modify the first module to following:
Private foo

Public Sub test()
    Debug.Print TypeName(foo)
End Sub
then the Redim no longer affects the foo, as expected.
@M.Doerner Module name is 'TestPurlinViabilityChecker'. The test method name is 'MinimizesPunchPattern_PanelsWide8_PanelsLong15_StringSize20_MinCant2Point5_MaxCant3Point5_PanelsBetweenColumns10_ReturnsTrue' which invokes the MinimizesPunchPattern on the System Under Test (SUT). I'm wondering if there's a more succinct way to name the test method.
I may just need to take a few deep breaths and accept the long names.
6:44 PM
IDK... feels like it's doing too much
Reading the code, it makes sense but from the name alone, it does give an impression that it's testing too many things.
In actuality, all we are doing is asserting that a failed selection doesn't alter the state. Thus ThrowsExecptionOnTrySetActiveSelection_DoesNotChangeTheActiveCodePane_ReturnsFalse would have been enough, IMO.
@this in many US states there is a Common Law Marriage which basically means that if you've lived together long enough you're considered married for things like wills. That could be considered being "passively married".
@FreeMan sigh.... #MassiveJokeFail
Just looking at the factual side of things. While I'm a native English speaker and my mother was an English major, things like "passive voice" aren't over my head, I just don't care enough to be bothered. I can speek it guud enough, so there you is
6:56 PM
Is there nothing in a VBA .cls file that indicates what the name of the class is/should be?
I'm adding a new implementation so the easiest thing is copy/pasta the .cls file and load that - I pulled it up in N++ looking for an internal name to change and didn't fine one.
i thought it was dictated by an attribute?
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
'@folder ("WebDriver.Implementations")
Option Compare Database
Option Explicit
I thought it woulda been in there, too...
I think it woudl have been VB_name, but - I don't think it's hard and fast either.
that crap was nuts
A: I am trying to update the data source of an oledb data adapter and nothing happens

KySotoIn the end a reddit user helped me figure it out, Their post was the thing that got everything rolling. What i needed to do was set the state of every datarow in my datatable to "Added" using the SetAdded method. Then i needed to set $DestCb.QuotePrefix = "[" and $DestCb.QuoteSuffix = "]" Then it...

Well, according to Vitosh Academy, not only is there a VB_name, but I'm missing some other headers, too:
  MultiUse = -1  'True
Attribute VB_Name = "CarWithDefaultProperty"
7:03 PM
how are you exporting?
i noticed that using the "proper" export it includes those lines
if you use SaveAsText it doesnt include them
interesting that Access.Application.SaveAsText acModule, ... doesn't seem to put the class header in there
i had to quit using it because something was happening that was causing it to export import junk
Indeed. I did confirm that was the case.
had to go back to the proper inport
My import routine (using Access.Application.LoadFromText acModule,) seems to work just fine when I've exported as above.
7:05 PM
but somehow it automagically knew what to does to do with it.
mine did too for like a month
I guess I'm about to find out how well Access likes importing a class w/o that little bit 'o header
then it exploded and was dying importing a class module
there was nothing i could find wrong with the project either, everything compiled, RD was cool with it for the most part
I've added the VB_Name attribute, we'll see what happens.
saves, makes a backup, then attempts import
@FreeMan export document modules (forms, reports) with that; use the VBIDE API to export class modules (that includes userforms)
7:06 PM
oh by the way, it doesnt care what the name is on loadfromtext because you specify where it is going
@MathieuGuindon oy!
makes me wonders whether tools like OASIS uses VBIDE im/ex for VBE stuff. I know it must use the LoadFromText/SaveAsText for all others.
@IvenBach have a separate test module per SUT
This is good:
> 1 file changed, 5 insertions(+), 10 deletions(-)
[rubberduck-vba/Rubberduck] build for commit 73a3ffd7 on unknown branch: AppVeyor build failed
7:13 PM
^ not my fault!!
interesting... I did a C&R in Access - RD started parsing as soon as it reopened the file. I ignored the spinning ducks and closed the DB - the duckies kept right on spinning... Kept spinning after opening the DB again...
I think I've got a clean parse, but I'm not sure...
Says it's Ready...
yes that's been reported before @FreeMan
parses again to be on the safe side.
In fact, you reported it. :)
I was about to say that it may have been me that reported it... :)
the issue is that you do have to do a manual reparse after loading the file
there is also something else weird that causes it to toggle on/off
that is, the 2nd file you end up seeing nothing.
Close 2nd and open 3rd, and you can see everything.
Close 3rd and open 4th, and you're back to nothing.
and to be honest with you I'm not sure I have a good fix for that issue because we get 3 unload events and 3 load events in rapid succession.
7:18 PM
if when there's a good way to cancel the parse, I'm sure that will get resolved.
that is not the problem, I don't think.
we are cancelling parse at least 6 times because of those events firing
Well... I right-clicked the CE and selected Add... | Existing File and had it import my class w/o the class header lines and. (drum roll, please)
2019-08-22 15:16:46.7255;ERROR-;Rubberduck.Parsing.VBA.DeclarationResolving.DeclarationResolveRunnerBase;Exception thrown acquiring declarations for 'Quarterly Report.ApptPlusPatientWebDownloader' (thread 78).;System.InvalidCastException: Unable to cast object of type 'Rubberduck.Parsing.Symbols.ProceduralModuleDeclaration' to type 'Rubberduck.Parsing.Symbols.ClassModuleDeclaration'.
   at Rubberduck.Parsing.VBA.DeclarationResolving.DeclarationSymbolsListener.EnterImplementsStmt(ImplementsStmtContext context) in C:\projects\rubberduck\Rubberduck.Parsing\VBA\DeclarationResolving\De
It seems the parser wasn't really happy with it.
did it compile?
the PE doesn't show the module under either Modules or Classes and it doesn't show in the CE (due to the resolver error, obvs...)
what was it originally?
it's just a class or standard module, right?
7:21 PM
Oh, nope, my bad, it does show under Modules in the PE. and it won't compile because you can't Implements in a standard module
it was originally a class.
And... this is what backups are for! :)
yeah that's bad
closed w/o saving. Added Version 1.0 Class header lines to .cls file. Opened the DB, imported via CE, hmmmm.....
The first time I tried that, Existing File was the only option enabled under Add. Now they're all available.
I wonder if the CE wasn't in a good state when I tried it the first time. (despite the manual parse)
not shocking... with the Class header lines, it shows up instantly in the PE under Class Modules and, once the parse is complete it shows up in the CE as expected.
Guess I'll need to tweak my export routine. However, for git usage, it seems to work just fine - when I import them, it seems to understand that they're classes even w/o the header.
(at least according to my faulty memory - will have to investigate further, but not today)
@FreeMan it seems to understand that they're classes even w/o the header - I'd be surprised if that were the case
Something needs to tell the VBE it's looking at a class, and it's not the file extension.
I've been doing about 99% exporting lately as I've been adding some new functionality, but I did test importing, and I'm pretty darn sure it worked since my code didn't implode most gracelessly... but, I'll do some additional testing to see what's what.
@Duga ~sigh. I'm an idiot
7:38 PM
Jun 11 at 14:13, by this
oh you're right. I'm an idiot
Feb 26 at 19:54, by Mathieu Guindon
oh, I'm an idiot
Jan 29 at 15:55, by KySoto
im an idiot
Nov 30 '18 at 4:14, by Comintern
Oh, it's because I'm an idiot.
everyone in the pond is an idiot at some point
Aug 3 '17 at 19:24, by Hosch250
Oh, I'm an idiot.
Jun 30 '15 at 23:58, by RubberDuck
I'm an idiot.
This isn't meritocracy.
This is idiocracy, kids.
May 1 at 23:07, by Mathieu Guindon
If you don’t feel like an idiot, just try to draw an ampersand on a whiteboard.
funny that the room has like 4 pages worth of everyone calling themselves an idiot
@MathieuGuindon I can.
The kind that looks like an e with a long tail.
I can't do the other version :D
I used to be able to, though.
7:46 PM
I usually do a variant of 8, but drawing a straight line from bottom right
same, and it still inevitably looks nothing like an ampersand
how is drawing an apersand on a whiteboard different than writing one?
you just start at the end pointing upwards, go with a bit of speed to make a larger rounding and then circle back into a downwards diagonal
that's basically the opposite direction of what I go in.
which could work, too.
OK, how do I star that whole series of posts???
7:51 PM
I start at the bottom right becuase it's easier to draw straight line to give a kind of guideline for the inverse half eight
that said, I realized that you could also draw a \, then overlap it with a variant of 2 and still get the same thing.
but that's 2 strokes, rather than 1 stroke.

We're all idiots

17 mins ago, 15 minutes total – 24 messages, 6 users, 0 stars

Bookmarked 6 secs ago by Mathieu Guindon

@MathieuGuindon should put on the mayor top hat & sash and procalim today as the idiot day
@this would also work with a question mark without dot
7:53 PM
probably give a golden key to.... someone.
Give the golden key to @all!
Ha! that guy's really got to be tired of all the random pings, but... he deserves it!
> last seen 1317d ago

« first day (1903 days earlier)      last day (92 days later) »