openTaggedSources
, is needed, which will open files to the location of the selected tag or tags.The resulting AppleScript is again quite concise:
on seescriptsettings()The structure directly parallels that used for the text completion script.
{displayName:"Find Definition using Ctags", shortDisplayName:"Ctags Definition", keyboardShortcut:"@^f", inContextMenu:"yes"}
end seescriptsettings
try
requireValidDocumentForCtags()
set tagfilepath to findTagFile()
set searchTerm to determineSearchTerm with userIntervention
set taglist to (pipeMatches of searchTerm out of tagfilepath thru "")
set tagsToOpen to (pickTags from taglist with multipleSelectionsAllowed)
openTaggedSources for tagsToOpen from tagfilepath
on error errMsg number errNum
if errNum is equal to 901 then
return
else if errNum is equal to 902 then
beep
return
else
error errMsg number errNum
end if
end try
Let's take a look inside the
openTaggedSources
handler. My approach is to dump all the selected tags back to the shell, where the shell script open-tag-files
will finish the job. Here's the handler:to openTaggedSources for tags from tagfileI pass the location of the tag file to the script, so that either absolute or relative paths can be used in the tag files. Otherwise, it's just passing the selected tags out as
--pass tags to external script that opens them in SEE
set exportTagsFile to "export TAGDIR=\"$(dirname " & (quoted form of tagfile) & ")\";"
set openTagFilesPipeline to join of {"printf " & quoted form of tags, "open-tag-files RelTo=\"$TAGDIR\""} by "|"
set openTagFilesScript to join of {UnixPath, exportTagsFile, openTagFilesPipeline, "&> /dev/null &"} by space
do shell script openTagFilesScript
end openTaggedSources
stdin
to open-tag-files
in a straightforward way. So let's look at
open-tag-files
:#! /usr/bin/awk -fThis is an
BEGIN {
FS="\t"
}
{
# Treat relative filenames as relative to RelTo
if ($2 ~ /^\//) {
filePath = $2
} else {
filePath = RelTo "/" $2
}
# Handle both numeric and regex patterns
if ($3 ~ /^[[:digit:]]+(;\")?$/) {
match($3, /^[[:digit:]]+/)
gotoLine = "-g " substr($3, RSTART, RLENGTH)
} else {
patternPlusExtras = substr($0, index($0, $3))
numTokens = split(patternPlusExtras, token, "/")
if (length(token[1])) {
# Pattern looks invalid, so can't specify the line
gotoLine = ""
} else {
exQuery = ""
for (n=2; n<=numTokens; n++) {
exQuery = exQuery "/" token[n]
if (token[n] !~ /[^\\](\\\\)*\\$/) {
break
}
}
exQuery = exQuery "/"
command = "cat '"filePath"' | sed -e '"exQuery" q' | wc -l"
command | getline lineCount
close(command)
gotoLine = "-g "lineCount
}
}
#printf("see %s \"%s\" &\n", gotoLine, filePath)
system("altsee "gotoLine" \""filePath"\" &")
}
awk
script which mostly consists of handling different ways that the tag file can be structured. Since the point is to provide a platform for experimenting with Ctags, it seems premature to commit to specific choices of absolute or relative paths, numeric line references or ex
patterns, extended fields from Exuberant Ctags or just vanilla Ctags lines. For what it is worth, I'm invoking Exuberant Ctags as ctags -n --fields=+a+m+n+S -R
(but there may well be better choices). At the end
open-tag-files
, I use altsee
to open the source files. This is a replacement for the see
command line tool that comes with SubEthaEdit. I find that see
is a bit of a hassle for this sort of use, so gave up on it for here (if you can get open-tag-files
to work cleanly with multiple selected files, I'd love to hear about how!). All the scripts and handlers need to be assembled into a compiled AppleScript in
~/Library/Application Support/SubEthaEdit/Scripts/
with the shell scripts set to be executable and on the path defined in the AppleScripts. If you're not sure where to put the shell scripts, I'd suggest creating a ~/Library/Application Support/SubEthaEdit/bin/
directory for SubEthaEdit-related shell scripts, and putting the scripts there. A compiled script with the needed shell script support is available for download.
No comments:
Post a Comment