15

Sometimes I miss the laziness of using an IDE that let me just write the attribute of a Java class and then let the IDE generate the required getter/setter.

Can Emacs do this?

Currently I just copy paste a pair of getter/setter form the previous line, and then copy paste and modify it. It's simple, but yet, make coding a little bit funnier :)

N.N.
  • 8,336
  • 12
  • 54
  • 94
swdev
  • 4,997
  • 8
  • 64
  • 106
  • 1
    If most of your getter and setters can be automatically generated by a tool, then you're really doing OOP the wrong way. See Anemic Domain Model anti-pattern, and why it is bad: http://martinfowler.com/bliki/AnemicDomainModel.html – Lie Ryan Feb 14 '11 at 09:05
  • 1
    Is there any reason you have to have just one editor? If certain things are easier to do in an IDE, I would just use the IDE for those things. – Peter Lawrey Feb 14 '11 at 09:10
  • 1
    well, actually it's Java requirements. So, if you had say,`int data`, in order for JSTL (java lib to easy access of object properties in web application) to be able to access it, we must implement setData() and getData(). The requirement is in the language itself. :) So, I think this no brainee process, should be left up to an automatic tools – swdev Feb 14 '11 at 09:12
  • @peter. Indeed. I was thinking of switching back and fort when I need a special capabilities exist in the IDE. :) But I want to solve it in Emacs. It's much more fun .. :) – swdev Feb 14 '11 at 09:17
  • @swdev, I believe it should be solvable in emacs as its very powerful. I don't consider getTers/setTers part of the Java language, just a common convension (one I tend to avoid because I think its ugly) – Peter Lawrey Feb 14 '11 at 09:22
  • @swdev: Is that really necessary? Unless you have SecurityManager in place, Java's reflection should allow you to see and modify any object's member variables, even the private ones. – Lie Ryan Feb 14 '11 at 09:33
  • 1
    I think you can acchieve this easily using [yasnippet][1] for emacs. [1]: http://code.google.com/p/yasnippet/ – phimuemue Feb 14 '11 at 09:41
  • 1
    @peter: Indeed. I just use the answer given by vpit3833. simpel, yet very useful :) @ryan : yes, it's a necessity, e.g, in a java Web App. It's part of java standard. :) – swdev Feb 14 '11 at 09:55
  • 1
    @ryan : btw, I did use java reflection to inspect the field, but eventough it's public (very2 bad maybe), but JSTL still need the setter/getter – swdev Feb 14 '11 at 09:55
  • 1
    @Lawrey, getters and setters are part of the convention for JavaBean properties. Many tools follow the convention and treat any getXxx/setXxx pair as a property. – Cheeso Feb 14 '11 at 21:26

4 Answers4

13

You asked specifically about generating a getter/setter pair. And you can write elisp to do this. But it may be interesting to look into a more general solution.

To solve this generally, I use ya-snippet . The name refers to "Yet Another Snippet package", so you can be sure the problem has been solved before. But I found ya-snippet to be the most useful, simple, and capable solution, for my needs.

For a property with a getter/setter, I type

prop<TAB>

...and I get a template that I can then fill in, like a form. I specify the name of the property, and everything else is generated. Very nice, easy.

enter image description here

This works for any micro-pattern you commonly use in code. I have snippets for a singleton, constructor, for loops, switch statements, try/catch, and so on.

The key with ya-snippet is there is no elisp code to write. Basically I just provide the text for the template, and it works. This is the ya-snippet code for the getter/setter snippet you see above:

# name : getter/setter property ... { ... }
# key: prop
# --
private ${1:Type} _${2:Name};
public ${1:Type} get$2 {
    ${3://get impl}
}
public void set$2($1 value) {
    ${4://set impl}
}

Everything above the "# --" is metadata for the snip. The "key" is the most important bit of that metadata - it is the short sequence that can be expanded. The name is shown on the yasnippet menu. The stuff below the # -- line is the expansion code. It includes several fill-in fields.

YAsnippet works for any programming mode in emacs (java, php, c#, python, etc) and it works for other text modes too.

Cheeso
  • 189,189
  • 101
  • 473
  • 713
  • 1
    amazing bro! I've never think a text editor can do that. Amazing.. many thanks! – swdev Feb 15 '11 at 13:07
  • 1
    @Cheeso: +1 and excavating a six weeks old thread: did you generate this animated *.gif* using some Emacs package? If so, which one and if not, how did you generate it? : ) – TacticalCoder Mar 21 '12 at 16:31
  • 1
    @TacticalCoder - no, not with an emacs package. Heh. Not everything runs in emacs, I guess. I used a tool called cropper, which is a "screen shot" utility that also has the ability to capture animated gifs. Find it on codeplex.com . – Cheeso Mar 21 '12 at 17:33
8

I'm using yasnippet as well, but this is a better snippet, imho:

# -*- mode: snippet -*-
# name: property
# key: r
# --
private ${1:T} ${2:value};
public $1 get${2:$(capitalize text)}() { return $2; }
public void set${2:$(capitalize text)}($1 $2) { this.$2 = $2; }
 $0

This code, for instance is generated in 10 keystrokes (r, C-o, Long, C-o, id, C-o):

private Long id;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }

I recommend binding yas/expand to C-o and not TAB to avoid clashes with e.g. auto-complete. I have this setup:

(global-set-key "\C-o" 'open-line-or-yas)
(defun open-line-or-yas ()
  (interactive)
  (cond ((and (looking-back " ") (looking-at "[\s\n}]+"))
     (insert "\n\n")
     (indent-according-to-mode)
     (previous-line)
     (indent-according-to-mode))
    ((expand-abbrev))
    (t 
     (setq *yas-invokation-point* (point))
     (yas/next-field-or-maybe-expand-1))))
(defun yas/next-field-or-maybe-expand-1 ()
  (interactive)
  (let ((yas/fallback-behavior 'return-nil))
    (unless (yas/expand)
      (yas/next-field))))

Note (expand-abbrev) somewhere inside this code. It allows me to expand e.g. bis to BufferedInputStream when I define:

(define-abbrev-table 'java-mode-abbrev-table
  '(
    ("bb" "ByteBuffer" nil 1)
    ("bis" "BufferedInputStream" nil 1)
    %...
))
N.N.
  • 8,336
  • 12
  • 54
  • 94
abo-abo
  • 20,038
  • 3
  • 50
  • 71
  • Thanks for this snippet. The transformation in the snippet doesn't work with current YASnippet, it should be `$(capitalize yas-text)` now. – whatacold Aug 07 '18 at 09:10
  • If we want to have a `getFooBar` method for its member variable `fooBar`, we'd better use `(upcase-initials yas-text)`, rather than `(capitalize yas-text)`, which will get us `getFoobar`. – whatacold Aug 07 '18 at 14:01
3

If you use the java-mode YASnippets by nekop you get the snippet prop which lets you define a private variable and it automatically makes a getter and a setter for that variable. The snippet reads as follows:

# -*- mode: snippet -*-
# name: property
# key: prop
# --
private ${1:String} ${2:name};$0

public $1 get${2:$(upcase-initials text)}() {
    return $2;
}

public void set${2:$(upcase-initials text)}($1 $2) {
    this.$2 = $2;
}

As can be seen this snippet does not differ much from the other answers except that it may be better formatted. Another advantage is that it is part of a package of snippets for Java.

N.N.
  • 8,336
  • 12
  • 54
  • 94
3

This site shows with elisp that can be pasted into your .emacs, how to generate getter and setter methods.

JDEE has the capability along with a lots more built in to itself.

vpit3833
  • 7,817
  • 2
  • 25
  • 25
  • wow. Thanks. The `defun insert-gettersetter (type field)` works for me! I've read about JDEE, and I think I'll try to use it some later. – swdev Feb 14 '11 at 09:26