How to define default syntax on files without extension on Sublime Text 2? - shell

I've read many posts dealing with this problem, but none has an answer to my question.
As said in the title, I would like to define a default syntax for all files which have no extension. In my case I would like to use the Shell syntax.
I've tried "View/Syntax/Open all with current extension as..." but for all files, I have to make again the manipulation.
I've tried the package "applySyntax" but it not seem to work with this configuration:
{
"name": "ShellScript/Shell-Unix-Generic",
"rules": [
{"file_name": "PRE_*$"}
]
}
All my files start with "PRE_[something]", someone know how to resolve this problem?
Thx!

I've found a Gist with a plugin to set the syntax based on the file name, I've modified it a bit to match files starting with PRE_:
import sublime_plugin
import os
class DetectFileTypeCommand(sublime_plugin.EventListener):
def on_load(self, view):
filename = view.file_name()
if not filename: # buffer has never been saved
return
name = os.path.basename(filename)
if name.startswith("PRE_"):
set_syntax(view, "Shell-Unix-Generic", "ShellScript")
def set_syntax(view, syntax, path=None):
if path is None:
path = syntax
view.settings().set('syntax', 'Packages/'+ path + '/' + syntax + '.tmLanguage')
print "Switched syntax to: " + syntax
You can go to Preferences->Browse Packages, and save it there ending with .py, I recommend creating a directory for it (e.g. DetectFileType/detect_file_type.py).

Related

Opening a Text File in Ruby

I am trying to create a program that will count the word frequency within a text file that I have created. I have a text file titled moms_letter.txt and this is my code:
word_count = {}
File.open("moms_letter.txt", "r") do |f|
f.each_line do |line|
words = line.split(' ').each do |word|
word_count[word] += 1 if word_count.has_key? word
word_count[word] = 1 if not word_count.has_key? word
end
end
end
puts word_count
The problem I am getting is when I go to run the file, I get the error:
there is no such file or directory - moms_letter.txt (Errno: : ENOENT)
Not quite sure why this is occurring when I have the text file created.
Any help is appreciated.
I am also newbie in Ruby, so thanks for the patience.
You must be executing your program from outside the directory where your moms_letter.txt file resides. You need to use an absolute path to open your file. Or, execute your program always from the directory where the .txt is. So, instead of using "moms_letter.txt" go with "complete/path/to/file/moms_letter.txt".
I'm fairly new to Ruby too, but have worked with text files a bit recently. It may seem like an obvious question, but is the text file you're trying to open in the same directory as your .rb file? Otherwise you'll need to include the relative path to it.
For troubleshooting sake, try File.new("temp.txt", "w") and then File.open("temp.txt", "r") to see if that works. Then you'll know if it's an issue with your code or with the txt file you're trying to access.
Also using File.exists?("moms_letter.txt") will help you determine whether you can access that file from within your .rb script.
Hope that helps!

Can't use io.open in home directory - Lua

I'm writing a Mac OS program, and I have the following lines:
os.execute("cd ~/testdir")
configfile = io.open("configfile.cfg", "w")
configfile:write("hello")
configfile:close()
The problem is, it only creates the configfile in the scripts current directory instead of the folder I have just cd' into. I realised this is because I'm using a console command to change directory, then direct Lua code to write the file. To combat this I changed the code to this:
configfile = io.open("~/testdir/configfile.cfg", "w")
However I get the following result:
lua: ifontinst.lua:22: attempt to index global 'configfile' (a nil value)
stack traceback:
ifontinst.lua:22: in main chunk
My question is, what's the correct way to use IO.Open to create a file in a folder I have just created in the users home directory?
I appreciate I'm making a rookie mistake here, so I apologise if you waste your time on me.
You have problems with ~ symbol. In your os.execute("cd ~/testdir") is the shell who interprets the symbol and replaces it by your home path. However, in io.open("~/testdir/configfile.cfg", "w") is Lua who receives the string and Lua doesn't interprets this symbol, so your program tries to open a file in the incorrect folder. One simple solution is to call os.getenv("HOME") and concatenate the path string with your file path:
configfile = io.open(os.getenv("HOME").."/testdir/configfile.cfg", "w")
In order to improve error messages I suggests you to wrap io.open() using assert() function:
configfile = assert( io.open(os.getenv("HOME").."/testdir/configfile.cfg", "w") )

Python: Check if a directory is an alias

Does python have a simple function for checking if a directory is an actual directory or if it's just an alias to another directory? I'm trying to list all files/folders in a directory but because of these alias folders, I'm getting a lost of stuff that looks like this:
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle
I know I can write a function that will compare paths and quit if it seems like I'm going in circles, but is there a simple function that does exactly that that I'm not aware of?
E.g.
os.isAlias( …pathname… )
Thanks!
Here's a version of os.path.realpath that works on Mac aliases as well as on symbolic links under Python 2:
from Carbon import File
def osx_realpath (path):
return File.FSResolveAliasFile(path, True)[0].as_pathname()
If you call osx_realpath on each directory before you recurse into it you should avoid duplication. Alternatively you could define something like
def is_osx_realpath (path):
return path == osx_realpath(path)
Here you have to worry a little about false negatives, however. If you filter for is_osx_realpath and the path you start with is an alias, your program will stop without looking at anything.
So far I don't know of a way to do this under Python 3. I have a question here where I'm hoping for an answer. Right now I can't do better than using subprocess.call to invoke something that does the check on the command line.
EDIT: I should add that not only is Carbon.File not available in Python 3, but it is deprecated and so is best avoided in Python 2 as well--however it's the most pragmatic solution I know of for Python 2 at present.
EDIT 2: here is a way to check if a file is an alias that I believe to be Python 3-friendly. However, I don't have code to resolve the alias. I believe you need PyObjC installed.
from AppKit import NSWorkspace
def is_alias (path):
uti, err = NSWorkspace.sharedWorkspace().typeOfFile_error_(
os.path.realpath(path), None)
if err:
raise Exception(unicode(err))
else:
return "com.apple.alias-file" == uti
(source)
The answer above is incorrect.
While it is true that Finder reports symlinks as alias, they are distinct things.
Symlinks are a basic feature of UNIX, but alias are a Apple only feature.
If you doubt this create a symlink to a directory and an alias. The symlink will be small typically 50-100 bytes, whereas the alias can be several MB.
os.path.islink( … ) will report symlinks, but not alias.
I am not sure how you would find them in Python, but the following link shows other methods.
https://stackoverflow.com/a/21151368/838253
You can check whether a file or directory is an alias with the GetFileInfo command in Mac OS X. GetFileInfo -aa foo prints a line with "1" if foo is an alias and "0" if not.
import subprocess
def is_alias(path):
return subprocess.check_output(["GetFileInfo", "-aa", path]) == "1\n"
Seems a little sad to spawn a process for every check, but I think this works with versions of Mac OS X since probably 10.4.4 (2006), 32-bit, 64-bit, Python 2 and Python 3. The version of GetFileInfo I have (from 2009) is a "universal" i386 + PPC binary.
GetFileInfo is part of Xcode, which is large, but you can download the command-line tools separately (see the "Separate Download" section here).
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/GetFileInfo.1.html
Old question, but I just ran into this myself.
I have no perfect method for checking if the file is an alias, however, if using mimetypes, python will return None for an alias or a symlink. Might be useful in some situations. I've only tested this in python 3.8 on macOS Big Sur.
import mimetypes
for idx, f in enumerate(filepaths):
type = mimetypes.guess_type(f)[0]
print(f"type is: {type}")
returns (without my added comments):
type is: None # <-- Folder Alias
type is: None # <-- File Alias
type is: text/x-python
type is: None # <-- Folder Alias
type is: video/mp4
type is: image/png
type is: None # <-- Folder Alias
type is: None # <-- Symlink
type is: image/png
type is: application/zip
type is: image/png
type is: image/jpeg
type is: None # <-- Symlink
I ran some files through exiftool just to see what types they returned, and aliases and symlinks both showed the following:
File Type : ALIAS
File Type Extension : alias
MIME Type : application/x-macos
You might be able to init the mimetypes for these, but haven't tested and not sure if it will give false positives if anything else shows up as application/x-macos

What is the best practice to read a file (under lib) while developing a gem?

I experienced some pain when deal with the "path" in developing a gem.
Here is the folder structure
production codes:
lib/gem_name/foo/templates/some_template.erb
lib/gem_name/foo/bar.rb
test codes:
test/gem_name/foo/bar_test.rb
In bar.rb, I read the template by:
File.read("templates/some_template.erb") => Errno::ENOENT: No such file or directory
when I run the unit test in bar_test.rb in RubyMine, it gives me the error:
Errno::ENOENT: No such file or directory - D:/.../test/gem_name/foo/templates/some_template.erb
Obviously the test in the path is wrong.
My question are,
How to deal with this issues?
What is the best practice to handle
such path problem while developing a gem?
Edit:
Since __FILE__ only returns the path of the file it is written, currently I define fname (see #ckruse's answer) like functions in every file I need it. It works but it is not elegant. Perhaps someone will have a better solution than mine on this. If so, please let me know.:)
You can always refer to the directory of the current file by File.dirname(__FILE__) and then use relative pathes, e.g.:
fname = File.dirname(__FILE__) + "/templates/some_template.rb"
File.read(fname)
Edit: To shortcut this just write a method:
def fname(file)
File.dirname(__FILE__) + "/../til/../project/../root/../" + file
end
Edit 3: You also could use caller to always refer to the directory of the calling file:
def fname(file)
path, _ = caller.first.split(':', 2)
File.dirname(path) + "/" + file
end

How can I get the path for the last created file in a directory using Ruby?

How can I get the path for the last created file in a directory using Ruby?
I think this is fairly brief:
Dir.glob(File.join(path, '*.*')).max { |a,b| File.ctime(a) <=> File.ctime(b) }
Dir.entries("testdir").reject{|f| f== '.' || f=='..'}.sort_by{|f| File.ctime(f)}.last
you can use the dir class to list all files and check the ctime or atime of the file object (ctime is the time the file was changed the last time, atime is the time the file was accessed the last time)
Dir.foreach("testdir") {|f| puts File.ctime(x) }
Dir.glob(root_path + ".").map{ |file| [file,File.ctime(file)]}.max.first
I added this method to my supermanpatches.rb file inside of railsapp/config/initializers to open my latest generated migration (in TextMate) without having to copy and paste the filename or anything like that:
def latestmigration
`mate db/migrate/#{Dir.glob(File.join(Rails.root, 'db', 'migrate', '*.rb')).max { |a,b| File.ctime(a) <=> File.ctime(b)} }`
end
‡: (FYI for ruby/rails beginners, initializer code is omnipresent and requires no class-to-filename scoping to be accessible from anywhere within rails)
NOTE: With windows (or mac) you could use the vim command instead of the mate command, and sublimetext can be configured to do this too, I think its called the subl command. mate & subl don't work by default though I think, so you have to set that up first

Resources