Sublime text 2, edit multiple selections sequentially, one at a time - sublimetext2

Here's a common scenario I find myself in quite often:
std::cout << "This is a really long line of code with a placeholder at the end: " << HERE_IT_IS << "\n";
std::cout << "This is another really long line of code with a placeholder at the end: " << HERE_IT_IS << "\n";
std::cout << "This is yet another really long line of code with a placeholder at the end: " << HERE_IT_IS << "\n";
It isn't uncommon that I have 10 - 20 of these lines where I want to replace HERE_IT_IS with 10 - 20 unique tokens (ie: a, b, c, d, ...).
Currently the way I accomplish this is to create that list somewhere else in the editor, each preceded by a unique character, select all of those unique characters with multiple selection, and copy, then select all of the HERE_IT_IS identifiers with multiple selection, and paste.
What I would love to be able to do is do multiple selection on HERE_IT_IS and then edit them one by one, pressing some hotkey combination in between each one. (ie: type a, hit hotkey to continue to next selected entity, type b, hit hotkey, type c, hit hotkey, ...).
I've searched around for something like this, but haven't found anything. Does anyone know if Sublime Text has this functionality? or if there is a plugin that does? OR how I could write a plugin that does? :)
All input on the issue is welcome. Thanks!

On Windows hit Alt+F3 to select similar identifiers/variables/etc.. and then run through them one at a time hitting F3. As you move through the occurrences of the identifier you can edit them individually. If you need to select multiple identifiers hit Ctrl+d and modify them at once. If you make a mistake hit Ctrl+u and undo your last selection from the list of similar identifiers/variables/etc...

Related

Doubts with some Vim commands and macros (The missing semester of your CS Education, parse XML to JSON with Vim macros)

I'm trying this exercise from The missing semester of your CS Education, Lecture 3: Editors (Vim):
(Advanced) Convert XML to JSON (example file) using Vim macros. Try to do this on your own, but you can look at the macros section above if you get stuck.
They give this solution:
Gdd, ggdd delete first and last lines
Macro to format a single element (register e)
Go to line with <name>
qe^r"f>s": "<ESC>f<C"<ESC>q
Macro to format a person (register p)
Go to line with <person>
qpS{<ESC>j#eA,<ESC>j#ejS},<ESC>q
Macro to format a person and go to the next person (register q)
Go to line with <person>
qq#pjq
Execute macro until end of file
999#q
Manually remove last , and add [ and ] delimiters
I don't understand commands like:
<C
^r"f>s":
S{<ESC>j#eA,<ESC>j#ejS}
Among others, could someone do a breakdown of the solution in order to understand the commands?
<C
This one is meaningless because you split the command at the wrong place. The correct place is between f< and C":
f< means "move the cursor to the next < on the line", see :help f.
C" means "cut the rest of the line and insert a "", see :help C.
^r"f>s":
^ means "move the cursor to the first printable character of the line", see :help ^.
r" means "replace the current character with a "", see :help r.
f> means "move the cursor to the next > on the fine", see :help f.
s": is actually s": ", meaning "replace the current character with ": ", see :help s.
S{<ESC>j#eA,<ESC>j#ejS}
S{ means "replace the whole line with a " at the correct indentation", see :help S.
<ESC> is the Escape key, see :help key-notation.
j means "go down one line", see :help j.
#e means "play back macro stored in register e", see :help #.
A, means "append a , at the end of the line", see :help A.
<ESC>, j, #e, j, and S} have already been explained.
All of that is pretty easy to piece out after a while (I rarely need to use Vim itself when answering Vim questions) but it sure is a lot to take in without the proper foundations.
That cryptic example is really a case of giving the reader a quasi-magical fish instead of teaching them how to fish. I am not sure what the people behind those "get rich quick" Vim articles and courses think they are achieving but questions like this one should make them pause a little.
The subject matter is much too complex to be covered in one lecture or in a short webpage so I would suggest you learn Vim properly instead of consuming context-free content like this.
If you haven't already, do $ vimtutor as many times as needed to get the basics right.
As instructed at the end of vimtutor, level up to the user manual :help user-manual. It's a hands-on tutorial that will guide you progressively through every feature, from basic to advanced. Go at your own pace and, most importantly, experiment along the way.
Keep an eye on anti-patterns and inefficient actions, find improvements, practice. Rinse. Repeat.

Is there a way to copy a single line of code but have it incrementally increase a number in said line of code for each paste?

I have a line of code I want to mass-paste into a file.
The line of code is "enchantment.level.x": "string". I want to paste this multiple times into my program, but each time I paste the line, I want x to increase by one.
So if line 2000 is "enchantment.level.1": "I", I would want line 2001 to be "enchantment.level.2": "I" (but I would change "I" to "II" manually).
Is there a way I can achieve this?
Thank you
I don't think there is any way to do what you want on each paste. But if you make all your pastes first then you can #rioV8's or my extension to accomplish the same goal.
The extension is Find and Transform that I wrote. It supports replacing with the match number (or index). Put this keybinding into your keybindings.json:
{
"key": "alt+m",
"command": "findInCurrentFile",
"args": {
"find": "(?<=enchantment\\.level\\.)x", // match the "x"
"replace": "${matchNumber}", // replace with the matchNumber
"isRegex": true
}
}
You could make that into a named setting too if you don't want to run it from the Command Palette.
${matchNumber} starts at 1. ${matchIndex} starts at 0.
You can use the extension Regex Text Generator to generate the new numbers.
Paste the line as often as you like
Select the number on all the lines with Multiple Cursors
use the extension and use (.*) for match regex and {{=i+1}} for generator expression

Emitting JSON with yaml-cpp?

I'm using yaml-cpp on a for a variety of things on my project. Now I want to write out some data as JSON. Since JSON is a subset of YAML, at least for the features I need, I understand it should be possible to set some options in yaml-cpp to output pure JSON. How is that done?
yaml-cpp doesn't directly have a way to force JSON-compatible output, but you can probably emulate it.
YAML:Emitter Emitter;
emitter << YAML:: DoubleQuoted << YAML::Flow << /* rest of code */;
Jesse Beder's answer didn't seem to work for me; I still got multiple lines of output with YAML syntax. However, I found that by adding << YAML::BeginSeq immediately after << YAML::Flow, you can force everything to end up on one line with JSON syntax. You then have to remove the beginning [ character:
YAML::Emitter emitter;
emitter << YAML::DoubleQuoted << YAML::Flow << YAML::BeginSeq << node;
std::string json(emitter.c_str() + 1); // Remove beginning [ character
Here is a fully worked example.
There's still a major issue, though: numbers are quoted, turning them into strings. I'm not sure whether this is an intentional behavior of YAML::DoubleQuoted; looking at the tests, I didn't see any test case that covers what happens when you apply DoubleQuoted to a number. This issue has been filed here.

COBOL .csv File IO into Table Not Working

I am trying to learn Cobol as I have heard of it and thought it would be fun to take a look at. I came across MicroFocus Cobol, not really sure if that is pertinent to this post though, and since I like to write in visual studio it was enough incentive to try and learn it.
I've been reading alot about it and trying to follow documentation and examples. So far I've gotten user input and output to the console working so then I decided to try file IO out. That went ok when I was just reading in a 'record' at a time, I realize that 'record' may be incorrect jargon. Although I've been programming for a while I am an extreme noob with cobol.
I have a c++ program that I have written before that simply takes a .csv file and parses it then sorts the data by whatever column the user wants. I figured it wouldn't be to hard to do the same in cobol. Well apparently I have misjudged in this regard.
I have a file, edited in windows using notepad++, called test.csv which contains:
4001942600,140,4
4001942700,141,3
4001944000,142,2
This data is from the us census, which has column headers titled: GEOID, SUMLEV, STATE. I removed the header row since I couldn't figure out how to read it in at the time and then read in the other data. Anywho...
In Visual Studio 2015, on Windows 7 Pro 64 Bit, using Micro Focus, and step debugging I can see in-record containing the first row of data. The unstring works fine for that run but the next time the program 'loops' I can step debug, and view in-record and see it contains the new data however the watch display when I expand the watch elements looks like the following:
REC-COUNTER 002 PIC 9(3)
+ IN-RECORD {Length = 42} : "40019427004001942700 000 " GROUP
- GEOID {Length = 3} PIC 9(10)
GEOID(1) 4001942700 PIC 9(10)
GEOID(2) 4001942700 PIC 9(10)
GEOID(3) <Illegal data in numeric field> PIC 9(10)
- SUMLEV {Length = 3} PIC 9(3)
SUMLEV(1) <Illegal data in numeric field> PIC 9(3)
SUMLEV(2) 000 PIC 9(3)
SUMLEV(3) <Illegal data in numeric field> PIC 9(3)
- STATE {Length = 3} PIC X
STATE(1) PIC X
STATE(2) PIC X
STATE(3) PIC X
So I'm not sure why that just before the Unstring operation the second time around I can see the proper data, but after the unstring happens incorrect data is then stored in the 'table'. What is also interesting is that if I continue on the third time around the correct data is stored in the 'table'.
identification division.
program-id.endat.
environment division.
input-output section.
file-control.
select in-file assign to "C:/Users/Shittin Kitten/Google Drive/Embry-Riddle/Spring 2017/CS332/group_project/cobol1/cobol1/test.csv"
organization is line sequential.
data division.
file section.
fd in-file.
01 in-record.
05 record-table.
10 geoid occurs 3 times pic 9(10).
10 sumlev occurs 3 times pic 9(3).
10 state occurs 3 times pic X(1).
working-storage section.
01 switches.
05 eof-switch pic X value "N".
* declaring a local variable for counting
01 rec-counter pic 9(3).
* Defining constants for new line and carraige return. \n \r DNE in cobol!
78 NL value X"0A".
78 CR value X"0D".
78 TAB value X"09".
******** Start of Program ******
000-main.
open input in-file.
perform
perform 200-process-records
until eof-switch = "Y".
close in-file;
stop run.
*********** End of Program ************
******** Start of Paragraph 2 *********
200-process-records.
read in-file into in-record
at end move "Y" to eof-switch
not at end compute rec-counter = rec-counter + 1;
end-read.
Unstring in-record delimited by "," into
geoid in record-table(rec-counter),
sumlev in record-table(rec-counter),
state in record-table(rec-counter).
display "GEOID " & TAB &">> " & TAB & geoid of record-table(rec-counter).
display "SUMLEV >> " & TAB & sumlev of record-table(rec-counter).
display "STATE " & TAB &">> " & TAB & state of record-table(rec-counter) & NL.
************* End of Paragraph 2 **************
I'm very confused about why I can actually see the data after the read operation, but it isn't stored in the table. I have tried changing the declarations of the table to pic 9(some length) as well and the result changes but I can't seem to pinpoint what I'm not getting about this.
I think there are a few things you've not grasped yet, and which you need to.
In the DATA DIVISION, there are a number of SECTIONs, each of which has a specific purpose.
The FILE SECTION is where you define data structures which represent data on files (input, output or input-output). Each file has an FD, and subordinate to an FD will be one or more 01-level structures, which can be extremely simple, or complex.
Some of the exact behaviour is down to particular implementation for a compiler, but you should treat things this way, for your own "minimal surprise" and for the same of anyone who has to later amend your programs: for an input file, don't change the data after a READ, unless you are going to update the record (of if you are using a keyed READ, perhaps). You can regard the "input area" as a "window" on your data-file. The next READ, and the window is pointed to a different position. Alternatively, you can regard it as "the next record arrives, obliterating what was there previously". You have put the "result" of your UNSTRING into the record-area. The result will for sure disappear on the next read. You have the possibility (if the window is true for your compiler, and depending on the mechanism it uses for IO) of squishing the "following" data as well.
Your result should be in the WORKING-STORAGE, where it will remain undisturbed by new records being read.
READ filname INTO data-description is an implicit MOVE of the data from the record-area to data-description. If, as you have specified, data-description is the record-area, the result is "undefined". If you only want the data in the record-area, just a plain READ filename is all that is needed.
You have a similar issue with your original UNSTRING. You have the source and target fields referencing the same storage. "Undefined" and not the result you want. This is why the unnecessary UNSTRING "worked".
You have a redundant inline PERFORM. You process "something" after end-of-file. You make things more convoluted by using unnecessary "punctuation" in the PROCEDURE DIVISION (which you've apparently omitted to paste). Try using ADD instead of COMPUTE there. Look at the use of FILE STATUS, and of 88-level condition-names.
You don't need a "new line" for DISPLAY, because you get one for free unless you use NO ADVANCING.
You don't need to "concatenate" in the DISPLAY, because you get that for free as well.
DISPLAY and its cousin, ACCEPT, are the verbs (only intrinsic functions are functions in COBOL (except where your compiler supports user-defined functions)) which vary the most from compiler to compiler. If your complier supports SCREEN SECTION in the DATA DIVISION you can format and process user-input in "screens". If you were to use IBM's Enterprise COBOL you'd have very basic DISPLAY/ACCEPT.
You "declare a local variable". Do you? In what sense? Local to the program.
You can pick up quite a lot of tips by looking at COBOL questions here from the last few years.
Well I figured it out. While step debugging again, and hovering the mouse over record-table I noticed 26 white spaces present after the last data field. Now earlier tonight I attempted to change this data on the 'fly' as it were, because normally visual studio allows this. I attempted to make the change but did not verify that it took, normally I don't have to, but apparently it did not take. Now I should have known better since the icon displayed to the left of record-table displays a little closed pad-lock.
I normally program C, C++, and C# so when I see the little pad lock it usually has something to do with scoping and visibility. Not knowing COBOL well enough I overlooked this little detail.
Now I decided to unstring in-record delimited by spaces into temp-string. just prior to the
Unstring temp-string delimited by "," into
geoid in record-table(rec-counter),
sumlev in record-table(rec-counter),
state in record-table(rec-counter).
The result of this was the properly formatted data, at least as I understand it, stored into the table and printed to the console screen.
Now I have read that the unstring 'function' can utilize multiple 'operators' such as so I may try to combine these two unstring operations into one.
Cheers!
**** Update ****
I have read the Mr. Woodger's reply below. If I could ask for a bit more assistance with this. I have also read this post which is similar but above my level at this time. COBOL read/store in table
That is pretty much what I'm trying to do but I don't understand some of things Mr. Woodger is trying to explain. Below is the code a bit more refined with some questions I have as comments. I would very much like some assistance with this or maybe if I could have an offline conversation that would be fine too.
`identification division.
* I do not know what 'endat' is
program-id.endat.
environment division.
input-output section.
file-control.
* assign a file path to in-file
select in-file assign to "C:/Users/Shittin Kitten/Google Drive/Embry-Riddle/Spring 2017/CS332/group_project/cobol1/cobol1/test.csv"
* Is line sequential what I need here? I think it is
organization is line sequential.
* Is the data devision similar to typedef in C?
data division.
* Does the file sectino belong to data division?
file section.
* Am I doing this correctly? Should this be below?
fd in-file.
* I believe I am defining a structure at this point
01 in-record.
05 record-table.
10 geoid occurs 3 times pic A(10).
10 sumlev occurs 3 times pic A(3).
10 state occurs 3 times pic A(1).
* To me the working-storage section is similar to ADA declarative section
* is this a correct analogy?
working-storage section.
* Is this where in-record should go? Is in-record a representative name?
01 eof-switch pic X value "N".
01 rec-counter pic 9(1).
* I don't know if I need these
78 NL value X"0A".
78 TAB value X"09".
01 sort-col pic 9(1).
********************************* Start of Program ****************************
*Now the procedure division, this is alot like ada to me
procedure division.
* Open the file
perform 100-initialize.
* Read data
perform 200-process-records
* loop until eof
until eof-switch = "Y".
* ask user to sort by a column
display "Would which column would you like to bubble sort? " & TAB.
* get user input
accept sort-col.
* close file
perform 300-terminate.
* End program
stop run.
********************************* End of Program ****************************
******************************** Start of Paragraph 1 ************************
100-initialize.
open input in-file.
* Performing a read, what is the difference in this read and the next one
* paragraph 200? Why do I do this here instead of just opening the file?
read in-file
at end
move "Y" to eof-switch
not at end
* Should I do this addition here? Also why a semicolon?
add 1 to rec-counter;
end-read.
* Should I not be unstringing here?
Unstring in-record delimited by "," into geoid of record-table,
sumlev of record-table, state of record-table.
******************************** End of Paragraph 1 ************************
********************************* Start of Paragraph 2 **********************
200-process-records.
read in-file into in-record
at end move "Y" to eof-switch
not at end add 1 to rec-counter;
end-read.
* Should in-record be something else? I think so but don't know how to
* declare and use it
Unstring in-record delimited by "," into
geoid in record-table(rec-counter),
sumlev in record-table(rec-counter),
state in record-table(rec-counter).
* These lines seem to give the printed format that I want
display "GEOID " & TAB &">> " & TAB & geoid of record-table(rec-counter).
display "SUMLEV >> " & TAB & sumlev of record-table(rec-counter).
display "STATE " & TAB &">> " & TAB & state of record-table(rec-counter) & NL.
********************************* End of Paragraph 2 ************************
********************************* Start of Paragraph 3 ************************
300-terminate.
display "number of records >>>> " rec-counter;
close in-file;
**************************** End of Paragraph 3 *****************************
`

Function to open a file and navigate to a specified line number

I have the output of recursive grep (actually ag) in a buffer, which is of the form filename:linenumber: ... [match] ..., and I want to be able to go to the occurrence (file and line number) currently under the cursor. This told me that I could execute normal-mode movements, so after extracting the file:line portion, I wrote this function:
function OpenFileNewTab(name)
let l:pair=split(a:name, ":")
execute "tabnew" get(l:pair, 0)
execute "normal!" get(l:pair, 1) . "G"
endfunction
It is supposed to open the specified file in a tab and then do <lineno>G, like I am able to do manually, to go to the specified line number. However, the cursor just stays on line 1. What am I doing wrong?
This question, by title alone, would be an exact duplicate, but it talks locating symbols in other files, while I already have the locations at hand.
Edit: My mappings for grep / ag are as follows:
nnoremap <Leader>ag :execute "new \| read !ag --literal -w" "<C-r><C-w>" g:repo \| :set filetype=c<CR>
nnoremap <Leader>gf ^v2t:"zy :execute OpenFileNewTab("<C-r>z")<CR>
To get my grep / ag results, I put the cursor on the word I want to search and enter <leader>ag, then, in the new buffer, I put the cursor on a line and enter <leader>gf - it selects from the start up to the second colon and calls OpenFileNewTab.
Edit 2: I'm on Cygwin, if it is of any importance - I doubt it.
Why don't you set &grepprg to call ag ?
" according to man ag
set grepprg=ag\ --vimgrep\ $*
set grepformat=%f:%l:%c:%m
" And then (not tested)
nnoremap <Leader>ag :grep -w <c-r><c-w><cr>
As others have said in the comments, you are just trying to emulate what the quickfix windows already provides. And, we are lucky vim can call grep, and it has a variation point to let us specify which grep program we wish to use: 'grepprg'.
Use file-line plugin. Pressing Enter on a line in the quicklist will normally open that file; file-line will make any filename of the form file:line:column (and several other formats) to open file and position to line and column.
I only found this (old) thread after I posted the exact same question on vi.stackexchange: https://vi.stackexchange.com/q/39557/44764. To help anyone who comes looking, I post the best answer to my question below as an alternative to the answers already given.
The gF command, like gf, opens the file in a new tab but additionally it also positions the cursor on the line after the colon. (I note the OP defines <leader>gf so maybe vim/neovim didn't auto-define gf or gF at the time this thread was originally created.)