How to capture output of ninja build system in Sublime Text 3? - sublimetext3

I am tring to set up the ninja build system in Sublime Text 3 that is not supported out the box. I generate my ninja.build file with meson. My build system is configured like this:
{
"cmd": ["ninja", "-C", "$folder/build/"],
"keyfiles": ["meson.build", "build.ninja"],
"file_regex": "^../([^:\n]*):([0-9]+)?.([0-9]+)?(.*):? (.*)$",
}
According to the manual I need to capture 2,3, or 4 groups with the Regex. Example error looks like this:
../src/View/Setup.vala:345.36-345.38: error: The name `loc' does not exist in the context of `View.Setup.setup_storage_location._lambda10_'
storage_location = loc;
^^^
I can jump with F4 to the error but the file is not opened even the first group is the file.
How can I get all 4 groups (file, line, column, message) even though ninja provide start (line, column) and end (line, column) of the error?

In order to capture all of the parts that Sublime supports (file, row/col and message) you need to craft a file_regex that captures just those parts. In this case that means that you need to match (but not capture) the end ranges so that you can pick up the error message on the end.
That regex might look something like this:
"file_regex": "^([^:]+):(\d+)?\.(\d+)-\d+\.\d+: (.*)"
Based on your output above, that would capture the filename, the first two values as row and column, then match but otherwise ignore the end range location, picking up everything else as the message.
Note also that the filenames in your output are relative filenames, and as a result Sublime will attempt to open them as such. However the current directory may not be what you expect because Sublime's current directory may be different than where your build is executing.
If you're seeing that even with your current regex the file doesn't seem to open (but a tab is created), this is the reason why that's happening.
To solve that problem you either need all filenames that are displayed in errors to be absolute paths, or you need to add the working_dir key to your build system to specify explicitly what the paths are relative to.
An example of that would be something like the following:
"working_dir": "${folder:${project_path:${file_path}}}",
This sets the working directory to be the first top level folder in the sidebar, falling back to the location where the current project is stored if there are no folders present, and falling back to the path of the current file if there's also no project.

Related

How to move folders with command line prompt in Windows 10?

Let's say we have next directory structure: parent\exampledir\exampledir\<very complicated folder structure like node modules>. By running only one command I want to have next structure: parent\exampledir\<very complicated folder structure like node modules>. How can I achieve this in command prompt?
I tried with: move exampledir\exampledir ., but I get a prompt asking me do I want to override exampledir. After I answer with Yes I get a message saying that access is denied. If I change the name of outer exampledir everything is fine and inner exampledir with all files and folders is correctly moved, but then there is one extra step where I need to delete outer exampledir.
You can do this in one command line, though technically it would be multiple commands using a FOR loop and then first renaming the source directory. You can enter multiple commands on a single line using a semi-colon. The following is written from my head so may not be technically accurate but should guide you to the correct way to write it:
d=blah\exampledir;REN "%d" "%d.bak";MOVE "%d.bak\%~nd" "%d"
This effectively moves the directory to a .bak, and then pulls the subdirectory of the same name back to the original name. If you put this into a batch file, don't forget to escape the % signs with a second one.
Another option could be to add * after the directory name so you MOVE exampledir\exampledir* exampledir\
it may be possible that using Git for Bash, you could launch the shell and use the Linux mv command which may work
Finally, if you want to make sure you back up your batch files, create a free GitHub account and either store it in a repo or create a Gist for one off things

How to search for files faster in Sublime Text 3

Right now I do ⌘t then scroll through autocomplete, or start typing the name (but half the time it doesn't find it).
Sublime doesn't find a file in many cases. For example, I typically have all my files called index.<ext> nested inside some folder. So I might have:
my/long/directory/structure/index.js
my/long/directory/structure2/index.js
my/long/directory/structure3/index.js
my/long/directory/structure.../index.js
my/long/directory/structuren/index.js
my/long/directory/index.js
my/long/directory2/index.js
my/long/directory.../index.js
my/long/directoryn/index.js
my/long/index.js
my/index.js
...
But in sublime you have to search for an exact path. I can't search this:
my directory index
And get results for directory, directory2, directory..., directoryn, I just get empty results because there is not my/directory. I can't remember the full folder path most of the time, so it takes a lot of effort to do so and I end up just navigating in the sidebar to find the file which takes some time.
Wondering if there is a better/faster way of doing this. Basically searching for a file by snippets/keywords of the complete path. So m dir would return my/long/directory, etc.
The first thing to note is that you do not have to search for an exact path; anywhere that Sublime provides you a list of items to select from and a text entry, fuzzy matching is in play. In your example searching just for idx will narrow down the list to all items that have those characters in that order, even if they're not adjacent to each other.
The entries show you visually how they're matching up, and there's a fairly sophisticated system behind the scenes that decides which characters make the best matches (relative to some hidden scoring algorithm):
In addition to this you can use multiple space separated terms to filter down the list. Each term is applied to the list of items resulting from the prior term, so they don't need to be provided in the same order as they appear in the file names.
This helps with searches where you know generally the name of the file, and from there can further drill down on segments of the path or other terms that will help narrow things down:
Something to note here is that as seen in these images, the folder structure is my/long/directory/structure, but the names of the files as seen in the panel don't include the my/ at the start.
In cases where your project contains only one top level folder, that folder isn't presented in the names of the files. Presumably this is because it's common to every file and thus not going to be a useful filter. As such trying to use my in the search field will return no matches unless one of the files has an m and a y somewhere in their filenames.
This isn't the case if there are multiple top level folders; in that case Sublime will include the root folder in the names of the files presented because now it's required to be able to distinguish between files in the different folders:
In addition to this, note that for any given filter text you enter in a panel, Sublime remembers the full text of the item that you selected while that filter text was being used, and uses that in it's scoring to prioritize the matches the next time you search in the same panel. The next time you search with the same term, Sublime will automatically pre-select the item that you picked last time under the theory that you probably want it again.
The search terms and their matches are saved in the session file and in your project's sublime-workspace files, so as you move from window to window and project to project you're essentially training Sublime how to find the files that you want.
My advice would be to try and flip your thinking a little bit. In my opinion the power of the fuzzy matching algorithm works best when you try to find files in a more organic way than trying to replicate the path entirely.
Instead, I would throw a few characters from the name of the file that I'm trying to find first, and then add another term that filters on some part of the path that will disambiguate things more; a term of idx s1 in this example immediately finds the two index.js files that are contained in structure1 folders, for example.
In a more real world example the names of the folders might contain the names of the components that they're a part of or something else that is providing a logical structure to the code, so you might do idx con to pull the index.js from the controller folder or idx mod to find the one in the model folder, and so on.
Regarding a better/faster way to do this I don't think there is one, at least in the general case. Sublime inherently knows every file that's in your project as a part of indexing all of the files to power other features such as Goto Symbol and it uses file watchers to detect changes to the structure of the open folders.
Anything else, including a third party plugin or package, would need to first do a redundant file scan to accumulate the list of files and would also have to replicate the file watching that Sublime is already doing in order to know when things change.

How to find the file path of a file in livecode

So, I'm incredibly new to LiveCode and I have an external file in the same directory as the .livecode file called 'words.txt', with english words, each on a new line. I plan to read this file into a variable and then pick a random word from that variable. However, I am stumped as to how I must find the file path and insert this into the syntax required for me to do this. My code is as follows:
put url ("binfile:" & filePathGoesHere) into dictionary
replace crlf with lf in dictionary
replace numToChar(13) with lf in dictionary
put any line of dictionary into randomword
The file path is supposed to be inserted into the code at filePathGoesHere. Once the program is compiled I will be moving it and its resources around a bit (from computer to computer), so, beyond the text file staying in the same folder as the compiled program, the file path will change. What extra code would I need to add to make this work, if the folder the compiled program and the txt file is in is called "MyProgram"?
Help is much appreciated, and if further specification is required I can provide it. I also have a folder called "resources" if moving it there can help.
If the stack you're building is for your own use, you can place external files anywhere, but if you're going to deliver your stack to other users, you need plan where you external files are going to be placed, and how.
An easy way to determine the path to a file that sits immediately outside your stack is using the stack's filename:
put the fileName of this stack into theFilePath
set the itemDel to "/"
put "words.txt" into the last item of theFilePath
Now theFilePath variable will an absolute path reference to your external file. If the file is placed inside a folder "TextFiles" you can do this:
put the fileName of this stack into theFilePath
set the itemDel to "/"
put "TextFiles/words.txt" into the last item of theFilePath
If you're going to deliver your stack to other people, you should write your external file/s into a common system folder, or you need to use an installer to define where your files/folders will be placed. Common folder paths are found using the specialFolderPath function:
put specialFolderPath("Documents") into the theFolderPath
A somewhat recent addition to LiveCode is a "Resources" folder -- specialFolderPath("Resources") -- which can be handy for delivering on desktop and mobile platforms. Also, keep in mind that few of these folders allow writing to existing files contained in them for security reasons. "Preferences" and "Documents" are two examples of folders where you can change the contents of files.
The LC dictionary contains details of each of the folders.
If you use the file: scheme instead of bindle: LiveCode will automatically convert end of line characters to LF, so that step may not be necessary. (Although you might need it if you are reading a text file produced in native Windows encoding on a Mac.) You don't even necessarily need to read it into a variable. You could do this:
put any line of URL ("file:" & specialFolderPath("resources") & "/words.txt") \
into tRandomWord

Finding words in a file present in a different file

I have a file with a list of properties.
Name
Description
BogusProperty_the_first
The full file has some 200 properties
I also have an xml file that references properties in the previous list, containing entries like;
<Item value="#Name#" length="32" description="Name" />
I want to remove from the first file all entries that are/are not present in the second file.
I do not need a perfect fit, it's OK if I treat some entries as being present in the second file when in fact they are not, so it's sufficient to test that "Description" occurs somewhere in the second file, I don't need to test that value="#Description#" occurs in a tag at the appropriate place in the DOM.
It would be bad to treat entries in the first file as not being in the second file if in fact they where.
The solution does not need to be completely automated or a single button click, but I do not want to check each item in the first file separately.
I am using notepad++, but would be open to using other tools if applicable.
The problem is small enough that writing a separate program to handle it, while straight forward, would not be worth it.
While writing the question I realised that notepad++ can solve this by copy pasting the second file into a copy of the first file.
The procedure I used was the following;
Write a seperate line in the first file with text that does not occur in the either of the two files. In my case I used asdf1234.
Copy the contents of the second file into the first.
Search for the following regexp with ".matches newlines" checked.
(?:\n|\r)([^\n\r]+)(?=(?:\n|\r).*asdf1234.*\1)
Replace with nothing.
???
Profit
To keep the entries that do occur in the second file use (?:\n|\r)([^\n\r]+)(?=(?:\n|\r))(?!.*asdf1234.*\1) to search.

Exclude files by wildcard through Tortoise SVN shell menu

I am using Tortoise SVN 1.6.16 in Windows 7. If I have a certain file type I want to exclude from future commits, I thought I could just go find a file of that type within my working folder, then right click it, and select "TortoiseSVN->Delete and Add to Ignore List->*.ext" where ext is the file extension of the file I clicked, as shown in the image below.
However, when I do this, it only excludes that specific file, and the next time I commit, all other files of that type still come up in the list to commit.
Am I doing something wrong? How can I just tell Tortoise or SVN to ignore all files of a certain type from future commits?
I had the same hunch as #Stefan: that you were probably seeing files in subdirectories and thinking those should have also been ignored even though you only applied the ignore to a single folder.
So if that is in fact the case, here is the recipe:
When you want to ignore files or patterns from a single directory:
Use the convenience menu command to add to the ignore list.
When you want to ignore files or patterns from a subtree:
Open the subversion properties (TortoiseSVN >> Properties) of the root of the subtree. Add or edit an entry for the svn:ignore keyword. The illustration shows an example where I have specified to ignore an obj subfolder as well as all files with a .user or .bak extension.
The secret, though, is in the specification--when you define the patterns to ignore, select the recursive choice as indicated here:
Unfortunately, there is one catch to this method: In my example, I had previously specified to ignore obj and *.user and I was adding just the *.bak pattern. When I apply recursively, it does not apply just the change (*.bak) but everything in the svn:ignore keyword (obj, *.user, and *.bak) to all subfolders. That may or may not be what you want, so be aware of it.
It ignores all bat files right, but not recursively! It only ignores them in the folder you added it to the ignore list.
You could also use Tortoise's global ignore pattern (if it's applicable to all your working copies):
TortoiseSVN -> Settings
General
Fill out the "Global ignore pattern" field, such as adding "*.ext" at the end of it, separating entries with a space.

Resources