Print the emacs package name that a function belongs to - elisp

In elisp, M-x find-function funcName
is there to go to the function definition. But, how to print the package name that a function belongs to?

The built-in library help-fns.el contains find-lisp-object-file-name. If you call this with a function name and type set to nil it will print the full file name of the file containing the definition.
On my system
(find-lisp-object-file-name 'find-function nil)
returns
"/Applications/MacPorts/Emacs.app/Contents/Resources/lisp/emacs-lisp/find-func.el"
which you can strip down as required. Note this behaves well on undefinded functions
(find-lisp-object-file-name 'I-dont-exist nil)
nil
(find-lisp-object-file-name 'icicle-find-file nil)
"/Users/swann/.emacs.d/elpa/icicles-20141215.1749/icicles-cmd1.el"
Items in packages will be found under in one of the directories in package-directory-list and package-user-dir. By default the latter is ~/.emacs.d/elpa. Under such a directory the given package is a subdirectory with name package-name-VERSION.

Related

How to load templates in subdirectories

I currently have all my html files in a flat directory templates/ and I load everything in with
tmpl := template.Must(template.ParseGlob("templates/*.html"))
But I'd like to now bring in some structure and put templates into folders, components, base, etc. But when I do my site stops working. I'm thinking it could be the above, or could it also be that I need to reference the path in the template?
example
{{ template "navbar" }}
would become
{{ template "components/navbar" }}
Slightly confused...
I'm also using the native go library not a framework, for now.
Go's glob does not support matching files in sub-directories, i.e. ** is not supported.
You can either use a third party lib (there are a number of implementations on github), or you could invoke filepath.Glob for each "level" of sub-directories and aggregate the returned file names into a single slice and then pass the slice to template.ParseFiles:
dirs := []string{
"templates/*.html",
"templates/*/*.html",
"templates/*/*/*.html",
// ...
}
files := []string{}
for _, dir := range dirs {
ff, err := filepath.Glob(dir)
if err != nil {
panic(err)
}
files = append(files, ff...)
}
t, err := template.ParseFiles(files...)
if err != nil {
panic(err)
}
// ...
You also need to keep in mind how ParseFiles works: (emphasis mine)
ParseFiles creates a new Template and parses the template definitions
from the named files. The returned template's name will have the
(base) name and (parsed) contents of the first file. There must be at
least one file. If an error occurs, parsing stops and the returned
*Template is nil.
When parsing multiple files with the same name in different
directories, the last one mentioned will be the one that results. For
instance, ParseFiles("a/foo", "b/foo") stores "b/foo" as the template
named "foo", while "a/foo" is unavailable.
This means that, if you want to load all the files, you have to ensure at least one of two things: (1) that each file's base name is unique across all template files, not just in the directory in which the file's located, or (2) provide a unique template name for each file by using the {{ define "<template_name>" }} action at the top of the file's contents (and do not forget the {{ end }} to close the define action).
As an example for the 2nd approach, let's say, in your templates you have two files that have the same base name, e.g. templates/foo/header.html and templates/bar/header.html and their contents are as follows:
templates/foo/header.html
<head><title>Foo Site</title></head>
templates/bar/header.html
<head><title>Bar Site</title></head>
Now to give the these files a unique template name you can change the contents to this:
templates/foo/header.html
{{ define "foo/header" }}
<head><title>Foo Site</title></head>
{{ end }}
templates/bar/header.html
{{ define "bar/header" }}
<head><title>Bar Site</title></head>
{{ end }}
After you do this, you can either execute them directly with t.ExecuteTemplate(w, "foo/header", nil), or indirectly by having other templates reference them using the {{ template "bar/header" . }} action.

python-sphinx - Display only function signature with autodoc?

In Sphinx is possible to include the signature of a function or method manually using the py:function (or py:method) directive:
.. py:function:: my_func(data, named=None, *args, *kwargs)
It is also possible to use autodoc directives to include and format the whole docstring of a function or method:
.. automethod:: my_func
I am wondering if there is a way of configuring autodoc to include and format only the signature, without the rest of the docstring, so that I don't have to do it manually.
autodoc-process-signature can be used here as well.
def process_signature(app, what, name, obj, options, signature, return_annotation):
return modified_signature, modified_return_annotation
# will be rendered to method(modified_signature) -> modified_return_annotation
def setup(app):
app.connect("autodoc-process-signature", process_signature)
http://www.sphinx-doc.org/en/master/_modules/sphinx/ext/autodoc.html
See autodoc's sphinx.ext.autodoc.between.
Return a listener that either keeps, or if exclude is True excludes, lines between lines that match the marker regular expression. If no line matches, the resulting docstring would be empty, so no change will be made unless keepempty is true.
If what is a sequence of strings, only docstrings of a type in what will be processed.

phoenix translate msg without put_locale

I have an array of users, each with its own locale.
I need to get a translation of the message into the language of each user.
...
Enum.map(user.tokens, fn(t) -> t.token end)
|> Sender.send(translated_msg(user.locale, msg))
...
defp translated_msg(locale, msg) do
message = Gettext.with_locale MyApp.Gettext, locale, fn ->
MyApp.Gettext.gettext(msg.body, msg.bindings)
end
message
end
where
msg = %{body: "%{login} added a new operation", bindings: %{login: current_user.login}}
But such code is not compiled
== Compilation error on file web/helpers/sender_helper.ex ==
** (ArgumentError) *gettext macros expect translation keys (msgid and msgid_plural) and
domains to expand to strings at compile-time, but the given msgid
doesn't.
Dynamic translations should be avoided as they limit gettext's
ability to extract translations from your source code. If you are
sure you need dynamic lookup, you can use the functions in the Gettext
module:
string = "hello world"
Gettext.gettext(MyApp.Gettext, string)
(gettext) lib/gettext/compiler.ex:196: anonymous fn/2 in Gettext.Compiler.expand_to_binary/4
expanding macro: MyApp.Gettext.dgettext_noop/2
web/helpers/push_helper.ex:23: MyApp.SenderHelper.translated_msg/2
expanding macro: MyApp.Gettext.dgettext/3
web/helpers/push_helper.ex:23: MyApp.SenderHelper.translated_msg/2
expanding macro: MyApp.Gettext.gettext/1
web/helpers/push_helper.ex:23: MyApp.SenderHelper.translated_msg/2
(elixir) lib/kernel/parallel_compiler.ex:117: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/1
How can I manually translate a message into another language?
Just like the error message says, if the string to translate is dynamic, you need to use Gettext.gettext/{2,3} passing in your app's Gettext module as the first argument. Since you're passing bindings as well, you need to use Gettext.gettext/3:
Gettext.gettext(MyApp.Gettext, msg.body, msg.bindings)

NSLocalizedString should be used directly for exporting XLIFF?

I used to use NSLocalizedString by custom function.
For example, to access Profile.strings, I define this function:
func LocalizedProfile(key: String, comment: String?) {
NSLocalizedString(key, tableName: "Profile", comment: comment ?? "")
}
And, called like this:
let localized = LocalizedProfile("Submit", comment: "For registration")
This method works fine except for exporting XLIFF.
On the Xcode 6.3.2, executting Export for localizationthrows error:
To get error information, I executed via command line:
xcodebuild -exportLocalizations -localizationPath ./xliff -project MyApp.xcodeproj -exportLanguage ja
And, I got this error:
Bad entry in file /Users/mono/Documents/Git/MyApp/Localization.swift (line = 29): Argument is not a literal string.
Defining custom localization method is very useful for me, but I also want to use exporting XLIFF feature.
Are there any methods to resolve this demands?
Export For Localization and xcodebuild -exportLocalizations both generate strings files by looking for invocations of NSLocalizedString(_:tableName:bundle:value:comment:) in code and uses the static values passed into the parameters to create the appropriate strings files.
This means that the only values you can pass into key, comment, value, and tableName are string literals.
Since you're using a wrapper function around NSLocalizedString(_:comment:) to localize your strings, the only time Xcode sees you calling NSLocalizedString(_:comment:) is in that one wrapper function with non-string-literal values, which is invalid.
What you really want to do instead is call NSLocalizedString(_:tableName:comment:) directly.
Alternatively, you can call Bundle.localizedString(forKey:value:table:) in your wrapper function, but then you have to manually create your own strings files for those key-value pairs.
/// - parameter comment: This value is ignored, but should be provided for
/// context at the call site about the requested localized string.
func LocalizedProfile(key: String, comment: String?) -> String {
return Bundle.main.localizedString(forKey: key, value: nil, table: "Profile")
}

RtlDosPathNameToNtPathName_U on "\\?\C:" Returns Invalid Path

Why is it that when I call RtlDosPathNameToNtPathName_U on the path \\?\C:, instead of getting back
\??\C:
I get back
\??\C:\฀\\?\C:
which is clearly incorrect?
Code snippet (in D):
struct CurDir { UnicodeString DosPath; HANDLE Handle; }
extern (Windows) static bool RtlDosPathNameToNtPathName_U(
in const(wchar)* DosPathName, out UnicodeString NtPathName,
out const(wchar)* NtFileNamePart, out CurDir DirectoryInfo);
wchar[] toNtPath(const(wchar)[] path)
{
UnicodeString ntPath;
CurDir curDir;
const(wchar)* fileNamePart;
enforce(RtlDosPathNameToNtPathName_U(path.ptr, ntPath,
fileNamePart, curDir));
try
{ return ntPath.Buffer[0 .. ntPath.Length / ntPath.Buffer[0].sizeof].dup; }
finally { RtlFreeHeap(RtlGetProcessHeap(), 0, ntPath.Buffer); }
}
writeln(toNtPath(r"\\?\C:")); //Returns the weird string
Update:
I figured out the problem -- see my answer.
RtlDosPathNameToNtPathName_U is giving you the correct output. The reason you see a weird-looking character in the middle is because UNICODE_STRINGs are not required to be null-terminated (which I'm sure you know already). The file name \??\C:\ is a completely valid native-format file name. I suspect what you really want is to prepend the device name instead of just referring to the GLOBAL?? directory like what RtlDosPathNameToNtPathName_U has done.
To do that, simply call NtQuerySymbolicLinkObject on \??\x:, where x is the drive letter that the path is using, and prepend the result. If it's a UNC path, prepend \Device\Mup. And so on for the other types of paths (if there are any).
I figured out the problem myself, with #wj32's help: I'd totally forgotten that the input to RtlDosPathNameToNtPathName_U needed to be null-terminated, and my code didn't handle that properly. Thanks for everyone's help!

Resources