How to automatically update tags file upon saving?


#1

Hi, I’m relatively new to all this, so a little confused. I’m using Haskell specifically and hasktags to generate tags files. This works successfully for me (although I use a command with a certain filtering and args to work most efficiently). What’s the easiest way to make my specific hasktags command re-run to update the tags file whenever I save a file in my project?


#2

Can you clarify how you are running hasktags to generate your tags file? Is this provided by a package you have installed, or externally via the command line?


#3

I’m currently just generating the tags with a bash command line operation.


#4

@olmokramer do you want to take a stab at writing a quick init.coffee function to add an on save process like this? :grinning:


#5

I’d be honored :slight_smile: I’ll see what I can do. I’m not familiar with haskell (and/or hasktags) at all, though, and I’m quite busy so it might take a few days before I have something.

@wolftune is there a specific command that you have to run from the command line (or if not from the command line, what else?) in your project to make this happen? Again, I don’t know a thing about haskell/hasktags, but maybe I can help you without learning a damned thing about it :stuck_out_tongue:


#6

Besides wanting anyone and everyone to get into Haskell, all I’m really saying is “is there a way to execute some command upon file saving?” The ideal has nothing to do with Haskell. It would be ideal to just have a way to say “execute X” (i.e. whatever CLI command I want to enter) each time a file is saved, and to make this really useful, it would be “each time a file of type Y” is saved, so then I’d just say “each time a .hs file is saved, run hasktags” but someone using another language could do whatever they want upon file saving…


#7

That’s definitely possible, I’ll try to have something up on friday or saturday :smile: I’ll assume you have language-haskell installed, or are you using some other haskell grammar?


#8

Yes, I use language-haskell, but I’m not sure it even matters in this case.


#9
  • You can subscribe to the Workspace.observeEditors event to be notified of all currently open editors and any new ones that are opened
  • You can subscribe to the TextEditor.onDidSave event to be notified when a particular text editor was saved
  • You can subscribe to the TextEditor.onDidDestroy event to be notified when a particular editor is destroyed (to clean up and stop listening to that editor’s events)
  • You can use BufferedProcess to run a command-line script or program and receive its output
  • You probably know better than us on how to execute the hasktags program
  • Bonus points for checking to see if it is a Haskell file when it is saved before running hasktags (you want to check every time it is saved because sometimes file types change along the way … like opened as a plain text file and then is force-assigned Haskell syntax, etc)

Those are the various components that just need to be plugged together to do what you want.


#10

Thanks, so that answers that this is possible, but all that is probably beyond me at this time. I’ll try to look into it ever.

If someone else is up for helping, I’d really appreciate the assistance. I’d love if someone could provide just simple instructions, paste this, sort of thing that was “check on save if this is a Haskell file, and if so, run [insert the exact hasktags command]” That would be super helpful.

It would take me a long while to figure this out myself, and I’m actually mostly trying to help some other folks who are more comfortable with Atom while I myself mostly am still sticking to Vim at this time…


#11

What about something like this as an init.coffee function:

{BufferedProcess} = require 'atom'
path = require 'path'

# Your command info here
command = 'hasktags'
args = ['--ctags']
fileExt = '.hs'

stdout = (output) -> console.log(output)
exit = (code) -> console.log("#{command} #{args} exited with #{code}")

atom.workspace.observeTextEditors (editor) ->
    editor.onDidSave ->
        if path.extname(editor.getPath()) is fileExt
            process = new BufferedProcess({command, args, stdout, exit})

You may also need to incorporate the project path (I’m not sure how hasktags is used).


#12

That seems good, but yes, I need to make sure that the command that runs is done in the project’s root directory? Will that be the default given Atom using the project root directory in the tree for the scope of what it considers the project? Or do I need to specify it beyond that?


#13

You can use atom.project.getPaths to get the project’s root directory.


#14

Perhaps this is better:

{BufferedProcess} = require 'atom'
path = require 'path'

# Your command info here
command = 'hasktags'
args = []
fileExt = '.hs'

stdout = (output) -> console.log(output)
stderr = (output) -> console.log(output)
exit = (code) -> console.log("#{command} #{args.join(' ')} exited with #{code}")
# Run in project root
options = {cwd: atom.project.getPaths()[0]}

atom.workspace.observeTextEditors (editor) ->
    editor.onDidSave ->
        if path.extname(editor.getPath()) is fileExt
            process = new BufferedProcess({command, args, options, stdout, stderr, exit})