My experience with 4coder

Hey,
I thought it would be useful to do a little write-up after using 4coder for about 3 months.

TLDR: 4coder FTW, thanks Allen !

Some context: I use 4coder daily at my current job, on a codebase written in C++ (not very modern C++).

You can find my customization file here https://gist.github.com/kelthalas/594c56b140a5a83b39196a5e5d4c06fc (bit of a mess, some stuff was taken from casey's file, other from default files and edited to my liking, and quite a few custom commands made from scratch)


I used to edit code either directly in VS2015 or in sublime text, so I wasn't very familiar with the cursor/mark paradigm. To ease with the transition, I wrote several custom commands to manipulate the mark in a familiar way (by word with ctrl+shift+arrows). In the end it wasn't too difficult to get used to it.


* One of the big thing I had to change was how *search*, *decls*, ... were handled :
I wanted the results to be shown in a small panel at the bottom of the current view and to be able to close that small panel with escape.
I also didn't want other commands like "open_in_other" to put their results in that small panel.
A lot of the already available commands use change_active_panel to find a view to place their result so I had to copy the code of those commands in new custom commands and change them slightly to put the result in my small panel. This is a bit annoying because now I have to manually check them each time 4coder has an update.

One possible fix would be to make the code of commands like list_all_locations_of_identifier into functions that takes a view parameter that indicates where to place the result buffer.


* I also had to modify "jump_to_location" (in 4coder_jump_parsing.cpp) to first check if a view didn't already have the file open instead of always opening it in the active view. This is because "seek_jump" calls change_active_panel before calling jump_to_location



* I had to workaround the fact that the iteration API (get_buffer_next) doesn't allow buffers to be killed during iteration (for kill all buffers and reload all buffers custom commands)



Bug Reports:

* When using the scroll bar with the mouse, if the cursor goes to another view, the scroll ends even though I am still holding left click. http://imgur.com/a/ddyTQ

* When I reopen a file using cmdid_reopen, the virtual whitespace doesn't work until I make a change to the buffer http://imgur.com/a/dhDrq

* I made a command to reload all buffers that have DirtyState_UnloadedChanges set (ie after svn update). However it seems like when that DirtyState_UnsavedChanges cannot be set at the same time. (See https://gist.github.com/kelthalas...e-4coder_custom_bindings-cpp-L884 even if I have unsaved changes, that if evaluates to true)

* Comments on the same line than an if that doesn't have {} breaks indentation. See http://imgur.com/a/pDyLm Same result if I write /* Some comment */

* goto_first_jump is bugged and jumps to the second one instead. See https://gist.github.com/kelthalas...le-4coder_custom_bindings-cpp-L17

* I tried to open every single cpp and h file in our codebase (around 1400+), but 4coder crashes inside that call to buffer_set_setting https://gist.github.com/kelthalas...e-4coder_custom_bindings-cpp-L335
It's probably not a good idea anyway. My workaround was to make a system to load our codebase by module/project/platform depending on what I'm working on at the time.

* 4coder identation doesn't like inline lambdas. See http://imgur.com/a/6KFPz

* Some C++ keywords are missing like auto and constexpr


That's it for now. I will post replies in this thread when I have new things to mention :)






Thanks a lot for the feedback! I'll respond to some of the things I can most clarify and the bugs I think I can fix soon.

kelth
A lot of the already available commands use change_active_panel to find a view to place their result so I had to copy the code of those commands in new custom commands and change them slightly to put the result in my small panel. This is a bit annoying because now I have to manually check them each time 4coder has an update.

One possible fix would be to make the code of commands like list_all_locations_of_identifier into functions that takes a view parameter that indicates where to place the result buffer.


The behavior of "change panel" has often been a sticking point for me basically since day one. I've been doing some organizing recently, and I haven't finished setting up all the systems/tutorials I want to start attacking this issue. As you have probably already seen. The big problem is we sometimes want to change how the framework thinks about views. Often that means we want "change panel" to mean something different than what it means by default, yet on the same hand we want that change panel meaning to be picked up and used by prewritten features like *search* and *decls*. I try to provide the calls as you suggest for some features, but I think a deeper solution is necessary, so a fix for this is coming sometime in the next few versions.


kelth
* I had to workaround the fact that the iteration API (get_buffer_next) doesn't allow buffers to be killed during iteration (for kill all buffers and reload all buffers custom commands)


I think one way to work around this is, instead of always getting the next buffer, instead always get the first buffer again, at least if you're killing all buffers. For reload all buffers I would be curious how you made it work, but my preferred method would be to iterate all the buffers and make an array of buffer_ids, then iterate that array.


kelth
* I made a command to reload all buffers that have DirtyState_UnloadedChanges set (ie after svn update). However it seems like when that DirtyState_UnsavedChanges cannot be set at the same time. (See https://gist.github.com/kelthalas...e-4coder_custom_bindings-cpp-L884 even if I have unsaved changes, that if evaluates to true)


It is not clear to me what the right way to handle this problem is. Once a buffer has both unloaded changes and unsaved changes, I am not sure which way the buffer should be treated. I could make a mark for it to be both now that I think about it, but for most purposes you have to decide how to treat as one of the other two... but I guess I could leave that decision up to the user. I have been assuming that should just always be treated as unloaded changes, but as I consider your post I realize I could try leaving it up to the user.


I will note the new bugs and take into consideration the points you've raised about how you're trying to make 4coder work. Thanks for the thoughts!
Mr4thDimention
For reload all buffers I would be curious how you made it work, but my preferred method would be to iterate all the buffers and make an array of buffer_ids, then iterate that array.


That's exactly what I did :)