author | Lars Hjemli <hjemli@gmail.com> | 2007-07-22 22:46:15 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2007-07-22 22:47:18 (UTC) |
commit | f405d0bf75427c627778027e9900359335d6774e (patch) (side-by-side diff) | |
tree | 2db75faf97df382edc7667cd8cd06e833361a937 | |
parent | eb45342e735818b3c68cbab9b61b23e79ae74418 (diff) | |
download | cgit-f405d0bf75427c627778027e9900359335d6774e.zip cgit-f405d0bf75427c627778027e9900359335d6774e.tar.gz cgit-f405d0bf75427c627778027e9900359335d6774e.tar.bz2 |
Add support for line number in url fragment
With this change, urls like http://hjemli.net/git/cgit/tree/ui-tree.c#43 can
be used to jump directly to the specified line number.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
-rw-r--r-- | cgit.css | 9 | ||||
-rw-r--r-- | ui-tree.c | 2 |
2 files changed, 10 insertions, 1 deletions
@@ -87,256 +87,265 @@ td#header, td#logo { background-color: #ddd; border-bottom: solid 1px #000; } td#header { font-size: 150%; font-weight: bold; padding: 0.2em 0.5em; vertical-align: text-bottom; } td#header a { color: #666; } td#header a:hoved { text-decoration: underline; } td#logo { text-align: right; vertical-align: middle; padding-right: 0.5em; } td#crumb, td#search { color: #ccc; border-top: solid 3px #555; background-color: #666; border-bottom: solid 1px #333; padding: 2px 1em; } td#crumb { font-weight: bold; } td#crumb a { color: #ccc; background-color: #666; padding: 0em 0.5em 0em 0.5em; } td#crumb a:hover { color: #666; background-color: #ccc; text-decoration: none; } td#search { text-align: right; vertical-align: middle; padding-right: 0.5em; } td#search form { margin: 0px; padding: 0px; } td#search input { font-size: 9pt; padding: 0px; width: 10em; border: solid 1px #333; color: #333; background-color: #fff; } div#summary { vertical-align: top; margin-bottom: 1em; } table#downloads { float: right; border-collapse: collapse; border: solid 1px #777; margin-left: 0.5em; margin-bottom: 0.5em; } table#downloads th { background-color: #ccc; } td#content { padding: 1em 0.5em; } div#blob { border: solid 1px black; } div.error { color: red; font-weight: bold; margin: 1em 2em; } a.ls-blob, a.ls-dir, a.ls-mod { font-family: monospace; } td.ls-size { text-align: right; } td.ls-size { font-family: monospace; } td.ls-mode { font-family: monospace; } table.blob { margin-top: 0.5em; border-top: solid 1px black; } table.blob td.no { border-right: solid 1px black; color: black; background-color: #eee; text-align: right; } +table.blob td.no a { + color: black; +} + +table.blob td.no a:hover { + color: black; + text-decoration: none; +} + table.blob td.txt { white-space: pre; font-family: monospace; padding-left: 0.5em; } table.nowrap td { white-space: nowrap; } table.commit-info { border-collapse: collapse; margin-top: 1.5em; } table.commit-info th { text-align: left; font-weight: normal; padding: 0.1em 1em 0.1em 0.1em; vertical-align: top; } table.commit-info td { font-weight: normal; padding: 0.1em 1em 0.1em 0.1em; } div.commit-subject { font-weight: bold; font-size: 125%; margin: 1.5em 0em 0.5em 0em; padding: 0em; } div.commit-msg { white-space: pre; font-family: monospace; } div.diffstat-header { font-weight: bold; padding-top: 1.5em; } table.diffstat { border-collapse: collapse; width: 100%; border: solid 1px #aaa; background-color: #eee; } table.diffstat tr:hover { background-color: #ccc; } table.diffstat th { font-weight: normal; text-align: left; text-decoration: underline; padding: 0.1em 1em 0.1em 0.1em; font-size: 100%; } table.diffstat td { padding: 0.2em 0.2em 0.1em 0.1em; font-size: 100%; border: none; } table.diffstat td.mode { white-space: nowrap; } table.diffstat td span.modechange { padding-left: 1em; color: red; } table.diffstat td.add a { color: green; } table.diffstat td.del a { color: red; } table.diffstat td.upd a { color: blue; } table.diffstat td.graph { width: 75%; vertical-align: middle; } table.diffstat td.graph table { border: none; } table.diffstat td.graph td { padding: 0px; border: 0px; height: 7pt; } table.diffstat td.graph td.add { background-color: #5c5; } table.diffstat td.graph td.rem { background-color: #c55; } div.diffstat-summary { color: #888; padding-top: 0.5em; } table.diff td { font-family: monospace; white-space: pre; } table.diff td div.head { font-weight: bold; padding-top: 1em; } @@ -1,174 +1,174 @@ /* ui-tree.c: functions for tree output * * Copyright (C) 2006 Lars Hjemli * * Licensed under GNU General Public License v2 * (see COPYING for full license text) */ #include "cgit.h" char *curr_rev; char *match_path; int header = 0; static void print_object(const unsigned char *sha1, char *path) { enum object_type type; unsigned char *buf; unsigned long size, lineno, start, idx; type = sha1_object_info(sha1, &size); if (type == OBJ_BAD) { cgit_print_error(fmt("Bad object name: %s", sha1_to_hex(sha1))); return; } buf = read_sha1_file(sha1, &type, &size); if (!buf) { cgit_print_error(fmt("Error reading object %s", sha1_to_hex(sha1))); return; } html(" blob: <a href='"); html_attr(cgit_pageurl(cgit_query_repo, "blob", fmt("id=%s", sha1_to_hex(sha1)))); htmlf("'>%s</a>",sha1_to_hex(sha1)); html("<table class='blob'>\n"); idx = 0; start = 0; lineno = 0; while(idx < size) { if (buf[idx] == '\n') { buf[idx] = '\0'; - htmlf("<tr><td class='no'>%d</td><td class='txt'>", + htmlf("<tr><td class='no'><a name='%d'>%1$d</a></td><td class='txt'>", ++lineno); html_txt(buf + start); html("</td></tr>\n"); start = idx + 1; } idx++; } html("</table>\n"); } static int ls_item(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned int mode, int stage) { char *name; char *fullpath; enum object_type type; unsigned long size = 0; name = xstrdup(pathname); fullpath = fmt("%s%s%s", cgit_query_path ? cgit_query_path : "", cgit_query_path ? "/" : "", name); type = sha1_object_info(sha1, &size); if (type == OBJ_BAD && !S_ISDIRLNK(mode)) { htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>", name, sha1_to_hex(sha1)); return 0; } html("<tr><td class='ls-mode'>"); html_filemode(mode); html("</td><td>"); if (S_ISDIRLNK(mode)) { htmlf("<a class='ls-mod' href='"); html_attr(fmt(cgit_repo->module_link, name, sha1_to_hex(sha1))); html("'>"); html_txt(name); html("</a>"); } else if (S_ISDIR(mode)) { cgit_tree_link(name, NULL, "ls-dir", cgit_query_head, curr_rev, fullpath); } else { cgit_tree_link(name, NULL, "ls-blob", cgit_query_head, curr_rev, fullpath); } htmlf("</td><td class='ls-size'>%li</td>", size); html("<td>"); cgit_log_link("log", NULL, "button", cgit_query_head, curr_rev, fullpath, 0); html("</td></tr>\n"); free(name); return 0; } static void ls_head() { html("<table class='list'>\n"); html("<tr class='nohover'>"); html("<th class='left'>Mode</th>"); html("<th class='left'>Name</th>"); html("<th class='right'>Size</th>"); html("<th/>"); html("</tr>\n"); header = 1; } static void ls_tail() { if (!header) return; html("</table>\n"); header = 0; } static void ls_tree(const unsigned char *sha1, char *path) { struct tree *tree; tree = parse_tree_indirect(sha1); if (!tree) { cgit_print_error(fmt("Not a tree object: %s", sha1_to_hex(sha1))); return; } ls_head(); read_tree_recursive(tree, "", 0, 1, NULL, ls_item); ls_tail(); } static int walk_tree(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage) { static int state; static char buffer[PATH_MAX]; char *url; if (state == 0) { memcpy(buffer, base, baselen); strcpy(buffer+baselen, pathname); url = cgit_pageurl(cgit_query_repo, "tree", fmt("h=%s&path=%s", curr_rev, buffer)); html("/"); cgit_tree_link(xstrdup(pathname), NULL, NULL, cgit_query_head, curr_rev, buffer); if (strcmp(match_path, buffer)) return READ_TREE_RECURSIVE; if (S_ISDIR(mode)) { state = 1; ls_head(); return READ_TREE_RECURSIVE; } else { print_object(sha1, buffer); return 0; } } ls_item(sha1, base, baselen, pathname, mode, stage); return 0; } |