Code Monkey home page Code Monkey logo

Comments (28)

leoliu avatar leoliu commented on May 27, 2024

I am not clear what the issue is. Could you elaborate? For example, does M-, help?

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

I mean, if I use M-. to jump to a tag definition and execute M-. again, it jumps to tag references, as written in the homepage:

M-. finds definitions or references according to the tag at point, i.e. if point is at a definition tag find references and vice versa.

However, after jump back to references, the cursor is not at previous tag position, i.e. my tag has multiple matches in *ggtags-global buffer:

match1.c:21: ....
match2.c:30:....
match3.c:50:....
match3.c:50:....

My cursor was previously on match3.c:50:...., but after jumping to tag definition and got back, my cursor is on match1.c:21:....

from ggtags.

leoliu avatar leoliu commented on May 27, 2024

Some how the comment I just wrote disappeared.

M-. twice doesn't get you back to where you were. M-. and then M-* does. You can see a list of locations that you have visited by C-c M-h. Does this help?

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

Uhm no, I don't want to go back where I first was. For example, I search a tag with multiple matches:

match1.c:21: ....
match2.c:30:....
match3.c:50:.... |
match3.c:50:....

| is the current cursor after two M-n. My cursor is on the match3 on *ggtags-global*. Suddenly, I want to go to the definition of the tag. So I press M-. to switch to the definition, since the tag at point is on the 3rd reference. After that, the cursor jumps to the definition of match3. After done looking at the definition of match3, I want to return the cursor to the line match3.c:50:.... and continue to browse other matches from that position. But currently, there's no way to do that.

I think it's convenient if references of a tag are looked up a lot, and we have to constantly refer to the definition.

from ggtags.

leoliu avatar leoliu commented on May 27, 2024

Ahh I see.

All search commands re-use the same buffer to display the results. So the second M-. will override the first M-.. If you need to save some search results you have to rename that buffer.

Is something like the following patch useful? https://gist.github.com/leoliu/9508659 Basically it makes it easy to rename the ggtags-global buffer. C-h r might not be a good key. Suggestions?

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

ggtags-navigation-rename-buffer is a nice feature. However, it does have better use for another feature I wil describe below. For now, even with ggtags-navigation-rename-buffer, although I can reserve the previous position of my tag, I cannot navigate with the buffer using M-p and M-n anymore. I suggest that each time a user jumps to a definition, he should be able to jump back to the most recent tag buffer he visits. For example, suppose I have symbol1 and I jump to it; instead of manually invoke ggtags-navigation-rename-buffer every time I want to jump to a definition (which is inconvenient) like symbol1, it should be invoked automatically and create *ggtags-symbol1*; after I finish with the definition, when I invoke M-., it should go back to *ggtags-symbol1* and focus on that buffer: ggtags-symbol1 should be focused and the uses of M-n and M-p should have effect on it, not another copy of ggtags-symbol1 with the name of ggtags-global.

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

Now as you created ggtags-navigation-rename-buffer, it can be used for more interesting feature. As you know, while navigating source code, we have to look at a lot of symbols (tags) for its references and definition. It would be nice if we can have a master tag table that stored a list of visited tags, each tag has it own buffer (possible with ggtags-navigation-rename-buffer) and keep the state of match that I previously visited. Here is an example to demonstrate how this feature looks like after implementing:

  • During the course of code navigation, I visited symbol1, symbol2 and symbol3. Each symbol has more than 10 matches.
  • For symbol1, I visited its definition and keep it ggtags-symbol1 at that match.
  • For symbol2, I visited its 8th match and keep it at that match.
  • For symbol3, I visited its 5th match and keep it at that match.

Later, when I want to refer back to where I stopped at each symbol, I can simply look up this master tag table to continue navigating that tag.

In summary, each visited tag has its own history; M-* will just cancel the current navigating session but not delete history of visited tag. It is not redundant with ggtags-view-tag-history because ggtags-view-tag-history serves as check points to go back to previous positions; ggtags-view-tag-history serves as a way to go back and forth on various points quickly in a current navigatin session. On the other hand, this new feature allows an organized way to navigate source code for a long period of time. User can organized relevant tags to fit their current task, i.e. I collect all important tags related to a feature. The master tag table should be able to save for later usage as well, i.e. after 1 year I need to work on that feature again, I can immediately pull back relevant information and refresh my memory in no time.

If want to implement this feature, I will create another issue to not make the discussion to broad. But I think, having a feature like this is really nice.

from ggtags.

leoliu avatar leoliu commented on May 27, 2024

Thanks. I agree this would be a more thorough solution. I'll come up with something soonish.

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

My proposed implementation:

  • Under the project root, create a file .ggtags.
  • The content of ggtags is just a list of tag groups (a more general name than feature, since people can organize task according to their other criteria), each feature contains a list of pairs, each pair contains a tag name and its currently selected match. Tag groupis named by user. For example:
 '('("server processing feature"  '((send . 3) (recv . 5) ....other pairs...))
   '("user interface feature" '((login_gui . nil) (profile_gui . 2) ... other pairs...)))

The number in tag pair is nth selection, i.e. 5 means 5th selection of multiple matches of a tag.

  • Upon a project root is enter, ggtags reads content in .ggtags into memory, and ready when user needs to query their saved tag group. A master tag table that list all the features is displayed when user needs:

server processing feature:
send :
...display multiple of send by querying GTAG database and highlight 3rd selection in a different colour ...
recv:
...display multiple of recv by querying GTAG database and highlight the 5th selection in a different colour ...
...other pairs...

User can choose to open individual tag group to display as well. So, you can implement this as a function, and master tag table is simply a result of calling this function for all tag group. The buffer for displaying tag group should be named the same as the tag group name assigned by user. Navigation function should be usable in the current visible ggtags buffer, not only *ggtags-global*. There should be a variable to keep track of the current selected tag buffer and navigation function should work on buffer specified in that variable.

from ggtags.

leoliu avatar leoliu commented on May 27, 2024

It is not difficult to have a way of persist a set of search results (buffers). But will this help your case? It should take no time to implement.

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

Sure I would love to have this feature. xcscope also allows search results to be appended to the same buffer:

New searches are appended to the cscope buffer, instead of overwriting. The user thus sees a history of cscope search results in this buffer, and is able to navigate through all of them. There is a size limit to keep the buffer from growing out of control.

https://github.com/dkogan/xcscope.el

However, I want to be able to separate tags into different groups and later retrieve it. That's why I suggest user should be able to create a tag group (i.e. feature), save it when he wants and later retrieves it back, either all or individual tag group.

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

And user should be able to delete unneeded tags in their tag groups as well.

from ggtags.

leoliu avatar leoliu commented on May 27, 2024

Hi tuhdo,

Could you take a look at the new command ggtags-save-to-register (bound to C-c M-SPC)? The UI is different than what you proposed but should integrate well with emacs.

I am keen on bring new features to ggtags provided they are useful i.e. show the use cases. So let me know if anything that can be particularly useful but are missing at the moment.

Thanks,
Leo

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

Hi Leo,

How do I use it? I executed ggtags-save-to-register, it asked me to save the content of ggtags-global into a register, I pressed "a". Then I list my register and nothing is in there.

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

Ok I notice that the buffer got name changed from global to its tag name and the tag state is saved in that buffer. Nicely done. Is there a way for existing tag buffer to be reused? For example, you should perform a name check to see if the same buffer exist, not generate a new buffer with different index (i.e. not ggtag-tag<1>).

I understand that for even for the same tag, different buffer can store different state i.e. *ggtags-tag* has the cursor on the 3rd match,ggtags-tag<1>` has the cursor on 10th match... For this problem, in each tag buffer, we should be able to mark our choices, i.e. I mark the 3rd and 10th matches, it should highlight.

Currently, if I save an old buffer to a register and use a new one, navigation functions (M-n, M-p...) are not usable on the old tag buffer. How do I switch back and continue navigating from there?

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

I found out that jump-to-register restore the previous sessions. However, I feel the approach using register is not convenient:

  • Registers are not visible. You can only view on register at a time using view-register, which means you have to remember which register stores which tag. This is tedious.
  • Registers are limited. There are only like, 24 registers. If we need more than that, we're screwed.
  • Cannot save to disk.
  • In my opinion, register is a less used feature of Emacs, with a hard to remember key bindings.

I think, you should make a buffer that records all the browsed tags and show this buffer in a table format (similar to ggtags-view-tag-history) with its name and its current selected match:

ID TAG Selected match
1 tag1 path/to/file:line-num: .... tag (highlighted)....

The function can be called ggtags-master-table. Select an entry in the table restore the current ggtags session to it. If we execute ggtags-master-table, check if ggtags-master-table buffer exists; if not create it; otherwise reuse it.

Doing it this way is much easier to add/update/delete tag entry. And we can even save to disk, but let's leave it later.

from ggtags.

leoliu avatar leoliu commented on May 27, 2024

Yes, I plan to add something like this for the 0.8.0 release.

Meanwhile could you try the ggtags-save-to-register again. Note, list-registers can show you all registers and in the upcoming 24.4 I have added a register preview feature. Check the NEWS file in emacs for details. Thanks.

Leo

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

I tried ggtags-save-to-register. It's nice that the tag buffers are not all over the place now. Currently, I think the register implementation is fine, since we can use Control for a register (i.e. register C-z, register C-x...) that increases the total of registers to more than 50. Later, it can be changed if people demand more tags.

A way to reduce the tag number is to allow nested tag groups. For example, a master table can have other master tables inside it; a master table includes:

  • tags as atomic elements.
  • itself.

For example, consider this use case: A project that has multiple shared libraries that different features reuse a lot, like a parsing library that is used in multiple features. I want to have the reference of this parsing feature in different features. You can imagine that you are writing a file explorer, except this is for tags: a file is equivalent to a tag, a directory is a tag group and a shortcut is a reference to a tag or tag group. A tree-like interface would make it easier and more intuitive to manage tree-like information.

But of course, we should finish the backend first before we create this user interface. Currently, you got the tag buffers save into registers properly. Now, you should implement master table (includes tags and itself). Then making an interface is easy.

Thanks for implementing these features.

from ggtags.

leoliu avatar leoliu commented on May 27, 2024

Searches are now recorded and can be re-run by C-c M-/ in ggtags-mode. Could you try it out? Thanks.

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

Nice feature! Now everything is automated.

There are a few issues though:

  • In *Ggtags Search History* buffer, only the first entry can be visited with one RET pressed; the other entries needs two RET to visit.
  • If a tag entry is no more available (i.e. the tag is deleted, or the file is removed):

    -- mode: ggtags-global; default-directory: "~/workspace/study/discrete_optimization/" --
    Global started at Fri Mar 21 13:33:26

global -v --result=grep --path-style=shorter --from-here=180:hw2/coloring/coloring_solver.cpp find_used_colors
hw2/coloring/coloring_solver.cpp:145: find_used_colors(v, used_colors);
hw2/coloring/coloring_solver.cpp:360: find_used_colors((v_it.second), used_colors);
hw2/coloring/coloring_solver.h:24: void find_used_colors(Vertex& v, std::set& used_colors);
hw2/coloring/flycheck-coloring_solver.cpp:145: find_used_colors(v, used_colors);
hw2/coloring/flycheck-coloring_solver.cpp:360: find_used_colors(
(v_it.second), used_colors);
Warning: source file './hw2/coloring/flycheck_coloring_solver.cpp' is not available.
hw2/coloring/flycheck_coloring_solver.cpp:145: find_used_colors((v_it.second), used_colors);
hw2/coloring/flycheck_coloring_solver.cpp:360: find_used_colors(
(v_it.second), used_colors);
7 objects located (using '/home/xtuudoo/workspace/study/discrete_optimization/GRTAGS').

Global found 7 references at Fri Mar 21 13:33:26

there's a warning. When, M-n/M-p visits this warning, find-file will be called to prompt for a file. I don't know if this is intended.

  • I don't understand what the line: xx in each entry provides what information to us. Clearly, it's not the line number in the source code.

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

In regards of the organization of tag group, I have an easier way to integrate it with your current implementation. Currently, each entry in *Ggtags Search History* is presented like this:

cmd: global -v --result=grep --path-style=shorter --from-here=180:hw2/coloring/coloring_solver.cpp find_used_colors
dir: /home/xtuudoo/workspace/study/discrete_optimization/
line: 9
text: hw2/coloring/flycheck-coloring_solver.cpp:360: find_used_colors(*(v_it.second), used_colors);

User should be easily group related tag by assigning it a label. Now, each entry in *Ggtags Search History* has one more line:

Labels: server-io, server

With the addition of labels, users should be able to query relevant tags based on the labels. For example, I want to query tag related server, I should be able to:

  • narrow it down in *Ggtags Search History*if *Ggtags Search History* already opened.
  • execute a command to query relevant tags if *Ggtags Search History* it not yet opened.

The label should be displayed as a link that when clicked, only tags in that label are visible.

Doing it this way, you can save the whole *Ggtags Search History* as it currently is (with the addition ofLabel:line) without doing anything else special. Do you agree?

from ggtags.

leoliu avatar leoliu commented on May 27, 2024
 In *Ggtags Search History* buffer, only the first entry can be visited with one RET pressed; the other entries needs two RET to visit.

This sounds like a bug. Could you provide a reproduction recipe? Don't be afraid to use any real project as long as they are easily accessible (e.g. on github) and not too large. Make sure you start with emacs -q.

if you visit a match whose file no longer exists, you will be prompted for the file. This is done by compile.el.

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

The recipe:

  • You can use any project you want. I used Global source code.
  • Find any tag by any way you want as long as there's at least one entry in Ggtags Search History.
  • Open Ggtags Search History with "C-c M-/".
  • Press RET on any entry. You will see that to visit any tag, you have to press RET twice, until you exit ggtags-navigation-mode by execute ggtags-navigation-mode-abort, which is bound to "M-*".

Hope that help!

On Fri, Mar 21, 2014 at 2:06 PM, Leo Liu [email protected] wrote:

In Ggtags Search History buffer, only the first entry can be visited with one RET pressed; the other entries needs two RET to visit.

This sounds like a bug. Could you provide a reproduction recipe? Don't be
afraid to use any real project as long as they are easily accessible (e.g.
on github) and not too large. Make sure you start with emacs -q.

if you visit a match whose file no longer exists, you will be prompted for
the file. This is done by compile.el.

Reply to this email directly or view it on GitHubhttps://github.com//issues/37#issuecomment-38253153
.

from ggtags.

leoliu avatar leoliu commented on May 27, 2024

I see. The bug will be fixed in the next commit. line is the line number in the ggtags-global buffer, a proximation of current match.

Regarding the labelling feature.

At the moment the history is sorted by access time, so the first one is always the last search etc. Would it make sense if I provide a command to sort history by project instead? The dir is usually the project root directory.

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

Well, I still think having the labelling feature would be very useful. For example, reading and understanding source code and remember related files and symbols are essential to source code maintenance. It would be a great help if I can record relevant tags during this process and organize them into a group. Later, I can use my saved tag group to explain it to new people quickly; or when I need to work with an existing feature I worked a long time ago again, I can use my saved tag group to refresh my memory and quickly get up to speed.

Currently, I have to do this process manually by writing to another file the relevant tag in the source code. Would be great if I can use source code browser to organize my tags.

I think this is perfectly fine, because we only assign label to existing entry in *Ggtags Search History* to enable a better way to organize a large collection of tags as the buffer grows, and not doing anything fancy.

from ggtags.

leoliu avatar leoliu commented on May 27, 2024

tuhdo,

Thanks a lot for insisting on/proposing these features.

They seem to indicate that we have different use patterns regarding ggtags. For example, I don't even understand why people want filtering on the elisp side by using helm or whatnot and ditch the fast index of a real DB based on the Btree data structure.

In my use case, C/PHP etc. I read the function/class, get to the definitions at point read and have some understanding then M-* back, and continue reading. I occasionally need to find a symbol (as in emacs) that is not at point, where I would use C-u M-., which provides standard completion support. So you see why minibuffer completion requires a C-u, it is not used as often.

Because of this difference, things that appear obvious to you might be obscure or confusing to me. So I wonder if it is possible to turn each proposal into something more concrete. For example, 1. your goal (such as code navigation/understanding) 2. you current workflow to achieve that goal (tools involved), preferably with example project and steps 3. comments on where it is inefficient and can be improved. To sum up make me feel your pain ;) BTW, this issue seems to go too long. Feel free to open new ones for feature proposals.

Thanks,
Leo

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

For example, I don't even understand why people want filtering on the elisp side by using helm or whatnot and ditch the fast index of a real DB based on the Btree data structure.

But which one do you think practically give results faster to a user? It depends on what you mean by fast. For example, Global can index 10 ms and gives result; Helm can index 100 ms and gives result (the numbers are made up; this is just an example). That's 10 times faster, but is it meaningful to us users? Less than 1 second and got feedback results, that's ought to be enough for everyone. Also, most of the data source we work with are finite and small. As a result, we do not need something faster for computer to process, but something faster to give us desired results. That's the goal.

Currently, Helm is quite fast. With the latest commit, a directory with 2400 files pos up nearly immediately (few seconds). Instead of hitting TAB repeatedly to narrow the candidates, Helm does it automatically and gives results as you type. I don't think with all my installed packages, I don't have that much interactive commands, and helm-M-x gives me the resulted function immediately with its key binding next to the command if the binding exists. Helm also helps me to reduce the amount of key strokes I have to hit.

For example, to enter the function ggtags-view-tag-history, without Helm, I have to enter ggtags, then hit TAB, type "-view", hit TAB again to complete. If ggtags-view has more than one candidate, than I have to hit more TAB. Helm helps me to be more productive like this: I enter ggtags, a list of candidates with ggtags is displayed immediately; I enter his (not history) and ggtags-view-tag-history is the only candidate.

A more intuitive example is helm-do-grep. With helm-do-grep, you enter your string or regex, and results got display immediately. If something does not exist, you will know. Compare to plain grep on terminal, you have to type the whole thing: grep, its option and files/directories to search, press RET, wait for result; if you fail (by typos, or such string/regex does not exist), you have to type again your query, press RET and got a bunch of results overloading your terminal screen (in Helm, your result buffer refresh every time you enter a new query and it's fast; also it may have a delay that you can configure). In Helm, the delay between a user's need and the results given by the computer is greatly reduced.

It's how fast the user gets their jobs done, not how fast the computer can process, matters. This is the key.

from ggtags.

tuhdo avatar tuhdo commented on May 27, 2024

This issue is finished. Closed. But we can keep on the discussion.

from ggtags.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.