Edit in JSFiddle

/*!
 * Completer v0.0.5
 * https://github.com/fengyuanchen/completer
 *
 * Copyright 2014 Fengyuan Chen
 * Released under the MIT license
 */

! function(a) {
    "function" == typeof define && define.amd ? define(["jquery"], a) : a(jQuery)
}(function(a) {
    "use strict";
    var b = a(window),
        c = a(document),
        d = function(b, c) {
            c = a.isPlainObject(c) ? c : {}, this.$element = a(b), this.defaults = a.extend({}, d.defaults, this.$element.data(), c), this.init()
        };
    d.prototype = {
        construstor: d,
        init: function() {
            var b = this.defaults,
                c = d.fn.toArray(b.source);
            c.length > 0 && (this.data = c, this.regexp = d.fn.toRegexp(b.separator), this.$completer = a(b.template), this.$completer.hide().appendTo("body"), this.place(), this.$element.on({
                focus: a.proxy(this.enable, this),
                blur: a.proxy(this.disable, this)
            }), this.$element.is(":focus") && this.enable())
        },
        enable: function() {
            this.active || (this.active = !0, this.$element.on({
                keydown: a.proxy(this.keydown, this),
                keyup: a.proxy(this.keyup, this)
            }), this.$completer.on({
                mousedown: a.proxy(this.mousedown, this),
                mouseover: a.proxy(this.mouseover, this)
            }))
        },
        disable: function() {
            this.active && (this.active = !1, this.$element.off({
                keydown: this.keydown,
                keyup: this.keyup
            }), this.$completer.off({
                mousedown: this.mousedown,
                mouseover: this.mouseover
            }))
        },
        attach: function(b) {
            var c, e, f = this.defaults.separator,
                g = this.regexp,
                h = g ? b.match(g) : null,
                i = [],
                j = this;
            h && (h = h[0], b = b.replace(g, ""), c = new RegExp("^" + d.fn.espace(h), "i")), a.each(this.data, function(a, d) {
                d = f + d, e = j.template(b + d), c && c.test(d) ? i.unshift(e) : i.push(e)
            }), "top" === this.defaults.position && (i = i.reverse()), this.fill(i.join(""))
        },
        suggest: function(b) {
            var c = new RegExp(d.fn.espace(b), "i"),
                e = this,
                f = [];
            a.each(this.data, function(a, b) {
                c.test(b) && f.push(e.template(b))
            }), this.fill(f.join(""))
        },
        template: function(a) {
            var b = this.defaults.itemTag;
            return "<" + b + ">" + a + "</" + b + ">"
        },
        fill: function(a) {
            var b;
            this.$completer.empty(), a ? (b = "top" === this.defaults.position ? ":last" : ":first", this.$completer.html(a), this.$completer.children(b).addClass(this.defaults.selectedClass), this.show()) : this.hide()
        },
        complete: function() {
            var a = this.defaults,
                b = a.filter(this.$element.val()).toString();
            return "" === b ? void this.hide() : void(a.suggest ? this.suggest(b) : this.attach(b))
        },
        keydown: function(a) {
            13 === a.keyCode && (a.stopPropagation(), a.preventDefault())
        },
        keyup: function(a) {
            var b = a.keyCode;
            13 === b || 38 === b || 40 === b ? this.toggle(b) : this.complete()
        },
        mouseover: function(b) {
            var c = this.defaults,
                d = c.selectedClass,
                e = a(b.target);
            e.is(c.itemTag) && e.addClass(d).siblings().removeClass(d)
        },
        mousedown: function(b) {
            b.stopPropagation(), b.preventDefault(), this.setValue(a(b.target).text())
        },
        setValue: function(a) {
            this.$element.val(a), this.defaults.complete(), this.hide()
        },
        toggle: function(a) {
            var b = this.defaults.selectedClass,
                c = this.$completer.find("." + b);
            switch (a) {
                case 40:
                    c.removeClass(b), c = c.next();
                    break;
                case 38:
                    c.removeClass(b), c = c.prev();
                    break;
                case 13:
                    this.setValue(c.text())
            }
            0 === c.length && (c = this.$completer.children(40 === a ? ":first" : ":last")), c.addClass(b)
        },
        place: function() {
            var a = this.$element,
                c = a.offset(),
                d = c.left,
                e = c.top,
                f = a.outerHeight(),
                g = a.outerWidth(),
                h = {
                    minWidth: g,
                    zIndex: this.defaults.zIndex
                };
            switch (this.defaults.position) {
                case "right":
                    h.left = d + g, h.top = e;
                    break;
                case "left":
                    h.right = b.innerWidth() - d, h.top = e;
                    break;
                case "top":
                    h.left = d, h.bottom = b.innerHeight() - e;
                    break;
                default:
                    h.left = d, h.top = e + f
            }
            this.$completer.css(h)
        },
        show: function() {
            this.$completer.show(), b.on("resize", a.proxy(this.place, this)), c.on("mousedown", a.proxy(this.hide, this))
        },
        hide: function() {
            this.$completer.hide(), b.off("resize", this.place), c.off("mousedown", this.hide)
        }
    }, d.fn = {
        toRegexp: function(a) {
            return "string" == typeof a && "" !== a ? (a = this.espace(a), new RegExp(a + "+[^" + a + "]*$", "i")) : null
        },
        espace: function(a) {
            return a.replace(/([\.\$\^\{\[\(\|\)\*\+\?\\])/g, "\\$1")
        },
        toArray: function(b) {
            return "string" == typeof b && (b = b.replace(/[\{\}\[\]"']+/g, "").split(/\s*,+\s*/)), b = a.map(b, function(a) {
                return "string" != typeof a ? a.toString() : a
            })
        }
    }, d.defaults = {
        complete: function() {},
        itemTag: "li",
        filter: function(a) {
            return a
        },
        position: "bottom",
        source: [],
        selectedClass: "completer-selected",
        separator: "",
        suggest: !1,
        template: '<ul class="completer-container"></ul>',
        zIndex: 1
    }, d.setDefaults = function(b) {
        a.extend(d.defaults, b)
    }, a.fn.completer = function(b) {
        return this.each(function() {
            a(this).data("completer", new d(this, b))
        })
    }, a.fn.completer.Constructor = d, a.fn.completer.setDefaults = d.setDefaults, a(function() {
        a("[completer]").completer()
    })
});
/*!
 * Completer v0.0.5
 * https://github.com/fengyuanchen/completer
 *
 * Copyright 2014 Fengyuan Chen
 * Released under the MIT license
 */
input{width:90%;padding:5px;}
.completer-container{background-color:#fff;border:1px solid #ccc;border-bottom-color:#39f;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-family:inherit;font-size:14px;line-height:normal;list-style:none;margin:0;padding:0;position:absolute}.completer-container li{background-color:#fff;border-bottom:1px solid #eee;cursor:pointer;margin:0;overflow:hidden;padding:.5em .8em;text-overflow:ellipsis;white-space:nowrap}.completer-container .completer-selected,.completer-container li:hover{border-left:1px solid #39f;background-color:#eee;margin-left:-1px}
<input type="text" completer data-separator="@" data-source="['gmail.com', 'live.com', 'yahoo.ne.jp', 'i.softbank.jp']" placeholder="メールアドレスを入力">