file system watcher doesn't work when used full filename as filter - vscode-extensions

I'm trying setup a file watcher for one specific file C:\test.json via workspace.createFileSystemWatcher
This is the code I use:
const watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern("C:\\", "test.json"));
watcher.onDidChange(uri => console.log("change", uri));
watcher.onDidCreate(uri => console.log("create", uri));
watcher.onDidDelete(uri => console.log("delete", uri));
For some reason events are not triggered, unless I replace filter test.json with *.json - then it works just fine.
Any ideas why complete filename doesn't work?

I see your question(s) ;>} on github. I'll post there as well.
It is interesting that this works:
const watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(vscode.Uri.file("C:\\Testing"), "test.json"));
Note that test.json is in a folder Testing.
This does not work - when test.json is at the root of C:
const watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(vscode.Uri.file("C:\\"), "test.json"));
So it looks like either vscode.Uri.file("C:\\") doesn't work properly at the drive root level or vscode.RelativePattern() doesn't work properly at the drive root level.
As we discussed on github (see API: createFileSystemWatcher() doesn't work when filter set to a specific file), the problem appears to be the trailing slash in C:\\. Since relative patterns like new vscode.RelativePattern(vscode.Uri.file("C:\\Testing"), "test.json") work and patterns like new vscode.RelativePattern(vscode.Uri.file("C:\\Testing\\"), "test.json") do not work.
But a backslash is required for a drive root level designation:
No, it doesn't. But it's because drive path requires trailing slash,
otherwise it's treated as relative path instead:
Use a backslash as required as part of volume names, for example, the
"C:" in "C:\path\file" or the "\server\share" in
"\server\share\path\file" for Universal Naming Convention (UNC)
names.
from your comment at https://github.com/microsoft/vscode/issues/162498#issuecomment-1295628237
so it does seem that vscode.RelativePattern() will not work at the drive root level because of the trailing slash (but the trailing slash is necessary and a simple vscode.workspace.createFileSystemWatcher(vscode.Uri.file("C:\\test.json")); does not work either).
We should update this answer with however the github issue is resolved - can your original new vscode.RelativePattern(vscode.Uri.file("C:\\"), "test.json") be made to work.

Related

Unison's "ignorenot" parameter does not work

I have the following instruction in my unison profile:
ignore = Path node_modules
ignorenot = Path node_modules/scaffold
Easy enough, right? Except that it doesn't work. It keeps on ignoring the node_modules/scaffold folder.
I even tried it with a regex:
ignorenot = Regex /node_modules/scaffold/.*
So what's going on here? I'm running unison 2.48.4
Apparently, when you ignore a directory, there is no way to un-ignore a descendant.
What you should do instead is ignore the directory's contents, and then un-ignore a specific child. This will work for example:
ignore = Path node_modules/*
ignorenot = Path node_modules/scaffold

Require Export changes requirements in every file

I'm new to Coq, and currently going through the Software Foundations series of tutorials.
However, I keep finding myself struggling with getting the Require Export part working on the first try, every file seemingly requiring a new strategy to work. This time, however, I am stuck entirely.
In one file (Lists.v) I am able to simply write
From LF Require Export Induction., and have it work just fine.
In the very next one (Poly.v), I can't load the Lists module at all,
From LF Require Export Lists.
(* ==> Cannot find a physical path bound to logical path matching suffix
<> and prefix LF. *)
Unless I first add the load path to the current folder:
Add LoadPath "~/Documents/code/coq/".
From LF Require Export Lists. (* Works perfectly! *)
However, next chapter in, and nothing seems to be working.
Here's what I've tried:
From LF Require Export Poly.
(* ==> Cannot find a physical path bound to logical path matching suffix
<> and prefix LF. *)
Add LoadPath "~/Documents/code/coq/".
From LF Require Export Poly.
(* ==> The file /Users/coffee/Documents/code/coq/LF/Poly.vo contains library Poly
and not library LF.Poly *)
Add LoadPath "~/Documents/code/coq/LF/".
From LF Require Export Poly.
(* ==> Cannot find a physical path bound to logical path matching suffix
<> and prefix LF. *)
Add LoadPath "~/Documents/code/coq/LF/".
Require Export Poly.
(* ==> Cannot load LF.Basics: no physical path bound to LF *)
Safe to say: I'm at a loss here, I have no idea what I'm doing or why it's not working.
It worked before, and nothing I can find online seems to give any good answers.
My _CoqProject file contains -Q . LF
I'm experiencing this issue both on Windows and Mac.
And I'm using the latest version of CoqIDE.

How to organize Lua module path and write "require" calls without losing flexibility?

Say I have a project, whose folder structure looks like below:
| main.lua
|
|---<model> // this is a folder
| |a.lua
| |b.lua
|
|---<view>
|a.lua
|b.lua
model/a.lua requries model/b.lua: require "b"
view/a.lua requries view/b.lua: require "b"
main.lua requries files in model and view.
Now I have problem to get these modules loaded correctly. I know I can fix it by changing the require calls to:
model/a.lua: require "model.b"
view/a.lua: require "view.b"
But if I do that, I have to modify these files every time when I change the folder structure.
So my questions are:
How to fix the module path issue without hard code paths in module files?
Why Lua doesn't use the module search rule of Node.js, which looks easier?
When you require a module, the string parameter from require gets passed into the module which you can access using the variable-argument syntax .... You can use this to include other dependent modules which reside in the same path as the current module being requireed without making it dependent on a fixed hard-coded module name.
For your example, instead of doing:
-- model/a.lua
require "model.b"
and
-- view/a.lua
require "view.b"
You can do:
-- model/a.lua
local thispath = select('1', ...):match(".+%.") or ""
require(thispath.."b")
and
-- view/a.lua
local thispath = select('1', ...):match(".+%.") or ""
require(thispath.."b")
Now if you change directory structure, eg. move view to something like control/subcontrol/foobar, then control/subcontrol/foobar/a.lua (formerly view/a.lua) will now try to require control/subcontrol/foobar/b.lua instead and "do the right thing".
Of course main.lua will still need to fully qualify the paths since you need some way to disambiguate between model/a.lua and view/a.lua.
How to fix the module path issue without hard code paths in module files?
I don't have any better cross-platform solution, maybe you should plan the folder structure early on.
Why Lua doesn't use the module search rule of Node.js, which looks easier?
Because Lua tries its best to rely only on ANSI C, which is really successful. And in ANSI C, there's no such concept of directories.
There are a couple approaches you can use.
You can add relative paths to package.path as in this SO answer. In your case you'd want to add paths in main.lua that correspond to the various ways you might access the files. This keeps all the changes required when changing your directory structure local to one file.
You can add absolute paths to package.pathusing debug.getinfo -- this may be a little easier since you don't need to account for all the relative accesses, but you still need to do this in main.lua when changing your directory structure, and you need to do string manipulation on the value returned by debug.getinfo to strip the module name and add the subdirectory names.
> lunit = require "lunit"
> info = debug.getinfo(lunit.run, "S")
> =info.source
#/usr/local/share/lua/5.2/lunit.lua
> =info.short_src
/usr/local/share/lua/5.2/lunit.lua
The solution is to add the folder of main.lua (project root) to package.path in main.lua.
A naive way to support folders of 1 level deep:
-- main.lua
package.path = package.path .. ";../?.lua"
Note for requires in (project root) will look up files outside of project root, which is not desirable.
A better way of to use some library (e.g.: paths, penlight) to resolve the absolute path and add it instead:
-- main.lua
local projectRoot = lib.abspath(".")
package.path = package.path .. ";" .. projectRoot .. "/?.lua"
Then in you source use the folder name to scope the files:
-- model/a.lua
require "model.b"
-- you can even do this
require "view.b"
and
-- view/a.lua
require "view.b"

Location of formatter files for VIM

I found the following code snippet on the internet, and want to use it in my own .vimrc.
augroup CodeFormatters
autocmd!
autocmd BufReadPost,FileReadPost *.py :silent %!PythonTidy.py
augroup END
However, I'm not quite sure where to put the PythonTidy.py script, so that it is accessible from everywhere.
Furthermore I read that using BufReadPre is better than BufReadPost, respectively FileReadPre, is that true?
As it stands, PythonTidy.py must be accessible through your PATH. If you have a convenient place already contained in there, e.g. ~/bin, just place it there.
Alternatively, you can place it somewhere into your .vim directory, and use something like expand('<sfile>:p:h') to resolve the directory of your Vimscript, and build a relative path from there.
As you want to filter the read buffer contents with the :%! command, you have to use the BufReadPost event; with BufReadPre, the buffer hasn't yet been read and nothing would be sent to the filter.
PythonTidy is a command line executable: put it somewhere in your $PATH.
You can also put it anywhere and use an absolute path in the autocmd:
autocmd BufReadPost,FileReadPost *.py :silent %!/path/to/PythonTidy.py

How do I tell if a file is contained in a directory?

What's the right way to tell if a file is contained within a given directory, or a subdirectory thereof?
I want something like:
if ([directoryPath contains: filePath]) {
// file is in directory, or in a subdirectory of directory.
}
Example:
ContainerPath: /Users/sfisher/Library/Application Support/iPhone Simulator/5.1/Applications/89A57CCB-250D-4D10-B913-EA456004B431/AppName.app
Not matching: /Users/sfisher/Library/Application Support/iPhone Simulator/5.1/Applications/89A57CCB-250D-4D10-B913-EA456004B431/Documents/db/Sample Data
Matching: /Users/sfisher/Library/Application Support/iPhone Simulator/5.1/Applications/89A57CCB-250D-4D10-B913-EA456004B431/AppName.app/Samples/1
I could convert everything to strings (including appending a "/" to the container directory) and check for a string match, but it seems there should be a built-in method for this.
In principle, your underlying desire is surprising impossible. A given file path may include through symbolic or hard links, making "containment" a very complicated question. These kinds of links are uncommon in iOS, but iOS is still Unix, and in Unix such things are legal.
So your real question is actually whether one path specifier (string) is contained in another. So checking the paths as strings is the correct approach.
I think a simple string match is the right way to do it:
if (![directoryPath hasSuffix:#"/"]) directoryPath = [directoryPath stringByAppendingString:#"/"];
if ([filePath hasPrefix:directoryPath]) {
// ...
}
Note that this doesn't deal with complications introduced by symlinks, or with relative paths.